开发者

django: control json serialization

开发者 https://www.devze.com 2023-02-13 10:39 出处:网络
Is there a way to control json serialization in django? Simple code below will return serialized object in json:

Is there a way to control json serialization in django? Simple code below will return serialized object in json:

co = Collection.objects.all()
c = serializers.serialize('json',co)

The json will look similar to this:

[
    {
        "pk": 1,
        "model": "picviewer.collection",
        "fields": {
            "urlName": "architecture",
            "name": "\u0413\u043e\u0440\u043e\u0434 \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430",
            "sortOrder": 0
        }
    },
    {
        "pk": 2,
        "model": "picviewer.collection",
        "fields": {
            "urlName": "nature",
            "name": "\u041f\u0440\u0438\u0440\u043e\u0434\u0430",
            "sortOrder": 1
        }
    },
    {
        "pk": 3,
        "model": "picviewer.collection",
        "fields": {
            "urlName": "objects",
            "name": "\u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u043d\u0430\u0442\u044e\u0440\u043c\u043e\u0440\u0442",
            "sortOrder": 2
        }
    }
]

You can see it's serializing it in a way that you are able to re-create the whole model, shall you want to do this at some point - fair enough, but not very handy for simple JS ajax in my case: I want bring the traffic to minimum and make the whole thing little clearer.

What I did is I created a view that passes the object to a .json template and the template will do something like this to generate "nicer" json output:

[
{% if collections %}
    {% for c in collections %}
{"id": {{c.id}},"sortOrder": {{c.sortOrder}},"name": "{{c.name}}","urlName": "{{c.urlName}}"}{% if not forloop.last %},{% endif %}
    {% endfor %}
{% endif %}
]

This does work and the output is much (?) nicer:

[
    {
        "id": 1,
        "sortOrder": 0,
        "name": "Город и архитектура",
        "urlName": "architecture"
    },
    {
        "id": 2,
        "sortOrder": 1,
        "name": "Природа",
        "urlName": "nature"
    },
    {
        "id": 3,
        "sortOrder": 2,
        "name": "Объекты и натюрморт",
        "urlName": "objects"
    } 
]

However, I'm bothered by the fast that my solution uses templates (an extra step in processing and possible performance impact) and it will take manual work to maintain shall I update the model, for example.

I'm thinking json generating should be part of the model (correct me if I'm wrong) and done with either native python-json and django implementation but can't figure how to make it strip the bits that I don't want.

One more thing - even when I restrict it to a set of fields to serialize, it will keep the id always outside the element container and inste开发者_运维知识库ad present it as "pk" outside of it.


That's really easy. Quick example:

from django.http import HttpResponse
from django.utils import simplejson

def simple_view(request):
    response = {'string': "test",
                'number': 42,
                'array': [1, 2, 3],
                'js_object': dict(foo="bar")}
    return HttpResponse(simplejson.dumps(response),
                        mimetype="application/json")

This view will return the equivalent of the following JSON:

{"string": "test",
 "number": 42,
 "array": [1, 2, 3],
 "js_object": {foo: "bar"}}

EDIT: And yes, Assaf Lavie is right, your template can spew invalid JSON.


I would suggest you use the json library to encode your data, instead of just constructing the json-like string yourself. The code above doesn't seem to handle escaping properly, for one thing. And there's not much to gain by writing your own serializer (except for bugs).


Rather than writing anything yourself, let Piston do the work of serializing Django models to JSON. By default it just serializes the model's fields, no metadata. And you can easily list which fields--even related fields--to include or exclude. No extra templates, and very little view code.


def view( request):
    m_all = list(model.objects.all().values())

    return HttpResponse(simplejson.dumps(m_all))

This should solve the problem. Using values() and converting to list should produce the result you wanted.

0

精彩评论

暂无评论...
验证码 换一张
取 消