如何在Django序列化器响应中包含额外数据?

时间:2009-01-05 16:07:36

标签: django json serialization

我正在尝试使用Django和jQuery进行livesearch。我所做的是让javascript使用getJSON函数询问一些数据,然后我在Django中设置一个视图,返回由Django序列化程序自动生成的JSON响应。

这很好用,它返回带有text / javascript内容类型的json响应。为了避免发送所有数据,(很多我不需要)我这样做了:

response.write(serializers.serialize("json", soknad_list, fields=('name', 'image', 'genre')))

但是,例如,'genre'字段是manyToMany字段,那么是否可以从genre.all.0获取值,而不仅仅是类型ID?

模型有一个函数get_absolute _url,是否可以在JSON响应中包含它,如果是这样的话?

所以我想我的问题是,是否可以在JSON响应中包含原始字段数据以外的内容,如果没有,您将如何解决我的问题?

3 个答案:

答案 0 :(得分:3)

Django的JSON序列化基于simplejson,您可以直接使用它并随意扩展以处理任何类型的对象。所以你在这里大多有两个选择:手动建立一个包含相关数据的dicts列表并将其传递给simplejson.dumps()(默认情况下支持字符串,列表,字符串和数字),或编写自己的json编码器,知道如何序列化您的特定数据集。 FWIW,这是一个(没有经过良好测试,但到目前为止工作)Django模型感知json编码器:

from django.utils import simplejson
from django.utils import datetime_safe
from django.utils.functional import Promise
from django.utils.translation import force_unicode
from django.utils.encoding import smart_unicode
from django.core.serializers.json import DjangoJSONEncoder

class ModelJSONEncoder(DjangoJSONEncoder):
    """
    (simplejson) DjangoJSONEncoder subclass that knows how to encode fields.

    (adated from django.serializers, which, strangely, didn't
     factor out this part of the algorithm)
    """
    def handle_field(self, obj, field):
        return smart_unicode(getattr(obj, field.name), strings_only=True)

    def handle_fk_field(self, obj, field):
        related = getattr(obj, field.name)
        if related is not None:
            if field.rel.field_name == related._meta.pk.name:
                # Related to remote object via primary key
                related = related._get_pk_val()
            else:
                # Related to remote object via other field
                related = getattr(related, field.rel.field_name)
        return smart_unicode(related, strings_only=True)

    def handle_m2m_field(self, obj, field):
        if field.creates_table:
            return [
                smart_unicode(related._get_pk_val(), strings_only=True)
                for related
                in getattr(obj, field.name).iterator()
                ]

    def handle_model(self, obj):
        dic = {}
        for field in obj._meta.local_fields:
            if field.serialize:
                if field.rel is None:
                    dic[field.name] = self.handle_field(obj, field)
                else:
                    dic[field.name] = self.handle_fk_field(obj, field)
        for field in obj._meta.many_to_many:
            if field.serialize:
                dic[field.name] = self.handle_m2m_field(obj, field)
        return dic

    def default(self, obj):
        if isinstance(o, Promise):
            return force_unicode(o)

        if isinstance(obj, Model):
            return self.handle_model(obj)

        return super(ModelJSONEncoder, self).default(obj)

HTH

答案 1 :(得分:2)

有一个方便的django第三方应用程序/序列化程序,允许您包含额外的数据。它还允许您包含模型关系并排除字段列表。

它可以在 http://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers

答案 2 :(得分:1)

我发现最简单的事情就是不要使用序列化器。我不知道为什么我之前没有想到这一点,但我只是使用了通用对象列表视图并将mimetype更改为text / javascript并制作了一个html模板的JSON模板。

非常简单,这样我就可以将我想要的所有数据都收集到JSON响应中。这样,您可以将可以添加到html模板的所有内容添加到JSON响应中,甚至可以进行分页。

我创建的视图的示例提取:

return object_list(request, queryset=object_list, template_name='search/results.js', template_object_name='result', paginate_by=12, mimetype='text/javascript')