【问题标题】:How to include extra data in the Django serializer response?如何在 Django 序列化程序响应中包含额外数据?
【发布时间】:2010-09-29 15:23:03
【问题描述】:

我正在尝试使用 Django 和 jQuery 进行实时搜索。我所做的是让 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 响应中包含原始字段数据以外的内容,如果没有,您将如何解决我的问题?

【问题讨论】:

    标签: django json serialization


    【解决方案1】:

    Django 的 JSON 序列化是基于 simplejson 的,你可以直接使用并随意扩展来处理任何类型的对象。所以你在这里主要有两个选择:要么手动构建一个包含相关数据的 dicts 列表并将其传递给 simplejson.dumps() (默认情况下支持字符串、列表、dicts 和数字),或者编写你自己的知道如何的 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

    【讨论】:

    • 嗨,谢谢,我一定会试试这个,非常感谢!如果我成功了,我会回复你。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我发现最简单的方法是根本不使用序列化程序。我不知道为什么我之前没有想到这一点,但我只是使用了一个通用的对象列表视图并将 mimetype 更改为 text/javascript 并制作了一个 JSON 模板,其中包含一个 html 模板。

      非常简单,通过这种方式我设法将我想要的所有数据放入 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')
      

      【讨论】:

      • 模板化 json 不是一个好主意,你绝对应该使用 json 序列化库
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      • 2020-02-05
      • 2021-04-09
      • 2017-05-24
      • 1970-01-01
      • 2019-01-19
      • 2019-06-04
      相关资源
      最近更新 更多