django: control json serialization

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-23 02:43:08

问题


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 instead present it as "pk" outside of it.


回答1:


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.




回答2:


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




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/5129794/django-control-json-serialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!