18

I currently have a Post model with 'title' and 'summary' fields. I'm retrieving all the Posts and returning them as JSON as part of a RESTful API interface.

Here's the basic approach

from django.core import serializers

def list_posts(request):
    posts = Post.objects.filter(owner=authenticated_user)
    serialized = serializers.serialize("json", posts, fields=('title', 'summary'))
    return HttpResponse(serialized, mimetype='application/json')

And I'm getting the following response back when I visit the corresponding route.

Current Response

[{"pk": 4, "model": "api.post", "fields": {"summary": "Testing", "title": "My Test"}}, {"pk": 5, "model": "api.post", "fields": {"summary": "testing again", "title": "Another test"}}]

This technically contains all the information my client-side needs to construct models (I'm using Backbone and could use collection.parse to construct what I need, but the server side should be responsible for structuring the response nicely). What troubles me about this is that it does not look like the standard API responses I'm used to seeing in reputable APIs. I think a JSON response like the following would be more 'standard'.

Desired Response

[{'summary': 'Testing', 'id': 4, 'title': 'My test'}, {'summary': 'My Test', 'id':5, 'title': 'Another test'}]

The output from serialize does not seem quite right for returning a collection of model instances in JSON as a response from an API call and this seems like a fairly common need. I'd like to return the fields information along with the id (or pk, if it must be called pk).

dgh
  • 8,969
  • 9
  • 38
  • 49
  • 1
    Check out the [tastypie](http://tastypieapi.org/) project. It provides a convenient way to add an API to your Django models and will serialize to output more like what you are expecting. – Austin Phillips Jan 21 '13 at 03:06
  • I ended up spending a few hours integrating tastypie into my API and experimenting with it before switching to the [Django REST Framework](http://django-rest-framework.org/) which was better suited for my project needs. IMO is a bit more flexible and well documented. Tastypie is still a great suggestion and a great REST framework for some applications. Thanks. – dgh Jan 21 '13 at 17:52

1 Answers1

26

What you want to achieve is subset of fields dumped to json.

What you're doing is serializing whole django's ORM objects. Not good.

Keep it simple:

import json

posts = (Post.objects.filter(owner=authenticated_user)
                     .values('id', 'title', 'summary'))
json_posts = json.dumps(list(posts))
Krzysztof Szularz
  • 5,151
  • 24
  • 35
  • Ah, so posts is a Django [ValueQuerySet](https://docs.djangoproject.com/en/dev/ref/models/querysets/#values) which returns dictionaries upon iteration. Haven't tried this, but it seems useful. Does this lose the advantage using the Django serializers had of automatically serializing all field types? I think json.dumps hickups on DateTimeField and other fields, but I haven't experimented with this. – dgh Jan 21 '13 at 18:01
  • 2
    For this, my friend, lean into [Django REST Framework](http://www.django-rest-framework.org/). – Krzysztof Szularz Feb 04 '16 at 15:09
  • What would be a good way to convert a queryset to a list of JSON objects, add a new field to each JSON object and return the new list in the response? – Divij Sehgal Mar 22 '17 at 11:27
  • 1
    @DivijSehgal http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset – Krzysztof Szularz Mar 23 '17 at 08:41
  • @KrzysztofSzularz did it that way :) Thanks again :) – Divij Sehgal Mar 23 '17 at 11:04