Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 335
JasonB Avatar asked Mar 16 '13 18:03

JasonB


People also ask

How do I return JSON data in Django REST framework?

In this article, we will create class-based views and combine this with the serializer class to return JSON representation for each HTTP request. For our class-based views, we will make use of a set of generic views, which help to achieve minimum lines code.

Is it necessary to use Serializers in Django?

If you work with Django rest API. So serializer is a good option to convert data into JSON format. If you don't want to use a serializer you can use Django form rather than serializer.

What is difference between serializer and ModelSerializer?

The ModelSerializer class is the same as a regular Serializer class, except that: It will automatically generate a set of fields for you, based on the model. It will automatically generate validators for the serializer, such as unique_together validators. It includes simple default implementations of .

What is serializing in Django?

Django's serialization framework provides a mechanism for “translating” Django models into other formats. Usually these other formats will be text-based and used for sending Django data over a wire, but it's possible for a serializer to handle any format (text-based or not).


4 Answers

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

like image 189
Ravindra Singh Panwar Avatar answered Sep 29 '22 16:09

Ravindra Singh Panwar


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)
like image 44
Sami N Avatar answered Sep 29 '22 16:09

Sami N


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

like image 41
gonz Avatar answered Sep 29 '22 17:09

gonz


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'))
like image 31
JChow Avatar answered Sep 29 '22 16:09

JChow