10

I am quite new to django and recently I have a requirement of a JSON output, for which I use the following django code:

data = serializers.serialize("json", Mymodel.objects.all())

It works great, except that I get a output of:

[{"pk": 8970859016715811, "model": "myapp.mymodel", "fields": {"reviews": "3.5", "title": .....}}]

However, I would like the output to be simply either:

[{"reviews": "3.5", "title": .....}]

or,

[{"id": "8970859016715811", "reviews": "3.5", "title": .....}]

I was wondering if someone could point me to the right direction as to how to achieve this.

4 Answers 4

8

You can add 'fields' parameter to the serialize-function, like this:

data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))

See: https://docs.djangoproject.com/en/dev/topics/serialization/

EDIT 1:

You can customize the serializer to get only the fields you specify.

From Override Django Object Serializer to get rid of specified model:

from django.core.serializers.python import Serializer

class MySerialiser(Serializer):
    def end_object( self, obj ):
        self._current['id'] = obj._get_pk_val()
        self.objects.append( self._current )

 # views.py
 serializer = MySerialiser()
 data = serializer.serialize(some_qs)
Sign up to request clarification or add additional context in comments.

2 Comments

I tried this - but it still outputs the "pk": 8970859016715811, "model": "myapp.mymodel", "fields": which I do not need
For some reason, your link on edit-1 does not work. So, I included the class and passed the queryset like so: data = serializer.serialize(mymodel.objects.all()) out = open("djangojson.json", "w") out.write(data) out.close() I get the following error:TypeError: expected a character buffer object which I did not get before.
4

You'll need to write a custom Json serializer. Something like this should do the trick:

class FlatJsonSerializer(Serializer):
    def get_dump_object(self, obj):
        data = self._current
        if not self.selected_fields or 'id' in self.selected_fields:
            data['id'] = obj.id
        return data

    def end_object(self, obj):
        if not self.first:
            self.stream.write(', ')
        json.dump(self.get_dump_object(obj), self.stream,
                  cls=DjangoJSONEncoder)
        self._current = None

    def start_serialization(self):
        self.stream.write("[")

    def end_serialization(self):
        self.stream.write("]")

    def getvalue(self):
        return super(Serializer, self).getvalue()

The you can use it like this:

s = FlatJsonSerializer()
s.serialize(MyModel.objects.all())

Or you could register the serializer with django.core.serializers.register_serializer and then use the familiar serializers.serialize shortcut.

Take a look at the django implementation as a reference if you need further customization: https://github.com/django/django/blob/master/django/core/serializers/json.py#L21-62

3 Comments

@rtindru Sorry but I didn't get what you mean, can you elaborate a little on your issue? Or maybe a new question with some code would be even better
self.first - no field first
can you give a example how to register using register_serializer
2

I just came across this as I was having the same problem. I also solved this with a custom serializer, tried the "EDIT 1" method but it didn't work too well as it stripped away all the goodies that the django JSON encoder already did (decimal, date serialization), which you can rewrite it yourself but why bother. I think a much less intrusive way is to inherit the JSON serializer directly like this.

from django.core.serializers.json import Serializer
from django.utils.encoding import smart_text    

class MyModelSerializer(Serializer):
    def get_dump_object(self, obj):
        self._current['id'] = smart_text(obj._get_pk_val(), strings_only=True)
        return self._current

Sso the main culprit that writes the fields and model thing is at the parent level python serializer and this way, you also automatically get the fields filtering that's already built into django's JSON serializer. Call it like this

serializer = MyModelSerializer()
data = serializer.serialize(<queryset>, <optional>fields=('field1', 'field2'))

2 Comments

django 1.4.1 don't have smart_text in django.utils.encoding
well ... then just strip away whatever code in get_dump_object in the parent for 1.4.1. The gist is changing as little as necessary from the original source.
1
import json

_all_data = Reporter.objects. all()

json_data = json.dumps([{'name': reporter.full_name} for reporter in _all_data])

return HttpResponse(json_data, content_type='application/json')

Here Reporter is your Model

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.