JasonB
JasonB

Reputation: 565

django serializers to json - custom json output format

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.

Upvotes: 10

Views: 29566

Answers (4)

JChow
JChow

Reputation: 268

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'))

Upvotes: 2

Ravindra Singh Panwar
Ravindra Singh Panwar

Reputation: 21

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

Upvotes: 1

gonz
gonz

Reputation: 5276

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

Upvotes: 4

Sami N
Sami N

Reputation: 1180

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)

Upvotes: 8

Related Questions