【问题标题】:Django : json serialize a queryset which uses defer() or only()Django:json序列化使用defer()或only()的查询集
【发布时间】:2011-01-06 23:39:09
【问题描述】:

现在我一直在使用 json 序列化程序,效果很好。

我不得不修改我开始使用 only()defer() 过滤器的查询,就像这样 -

retObj = OBJModel.objects.defer("create_dt").filter(loged_in_dt__gte=dtStart)

完成上述操作后,突然 json 序列化程序返回空字段 -

{"pk": 19047, "model": "OBJModel_deferred_create_dt", "fields": {}}

如果我删除 defer(),序列化程序会正确地提供所有数据。

import json
from django.utils import simplejson
from django.core import serializers
json_serializer = serializers.get_serializer("json")()
retObj = OBJModel.objects.defer("create_dt").filter(loged_in_dt__gte=dtStart)
json_serializer.serialize(retObj, ensure_ascii=False)

我已经为此挠头了一段时间。任何见解都会很棒。

注意:我使用的是 django 1.1

【问题讨论】:

  • create_dt 是什么类型的字段?查看 Django 中的票证,仅存在一些错误并推迟。也许您的就是其中之一,或者是一个新错误。我不明白为什么它会这样做而不是一个错误。我希望我被证明是错的:)
  • 它是 models.DateTimeField(auto_now_add=True) 。我希望我没有隐藏错误..

标签: django json serialization


【解决方案1】:

我认为这是某种错误。以下是一种解决方法。在调用序列化之前执行此操作。您会受到性能影响,但可能比序列化整个对象要小。

for obj in qs:
    for attr in qs.query.deferred_loading[0]:
        obj._meta.local_fields.append(qs.model._meta.get_field(attr))

【讨论】:

    【解决方案2】:

    我对您期望序列化程序在延迟字段方面的表现感到困惑......我可能遗漏了一些东西......

    doc for json serialization 说:

    请注意,如果您直接使用该模块进行序列化,则并非所有 Django 输出都可以不加修改地传递给 simplejson。特别是,惰性翻译对象需要为它们编写特殊的编码器。

    文档说的是惰性翻译,但我认为任何惰性操作都适用。

    我认为,如果您没有编写某种特殊的编码器来负责获取(访问)延迟字段的正确值,那么您所看到的只是正确的输出。

    在您发表评论后编辑:啊,我错过了没有其他字段被编码的事实。其他字段的类型是什么?我们可以看看你的模型吗?默认编码器对 FK 和 M2M 字段的处理方式不同 - 但我在 django.core.serializers.python.Serializerdjango.core.serializers.json.Serializer 上看不到任何可以解释为什么其他非延迟字段没有编码的内容...

    经过进一步调查后进行编辑: 上面 json 有效负载中的 OBJModel_deferred_create_dt 让我进一步挖掘。这似乎是从 django 的基础 Model 类中的 __reduce__ 方法调用 django.db.models.queryutils.deferred_class_factory() 的结果。 deferred_class_factory()

    返回一个类对象,它是“模型”的副本,其中指定的“属性”被替换为 DeferredAttribute 对象。 “pk_value”将延迟属性与模型的特定实例联系起来。

    这就是事情变得模糊的地方(对我来说!):实际上,酸洗是针对您实际的OBJModelproxy model 进行的。此代理模型应返回 - 当被询问时 - 原始模型的非延迟字段。但在你的情况下,它似乎不是。

    我会尝试设置一个小测试,看看我是否可以复制问题。

    【讨论】:

    • hmm.. 当我们推迟一个字段时,该字段不会被检索到。但其余数据被检索。因此,当您将它传递给 JSON 时,它实际上应该对其进行编码。我可以理解它不编码延迟字段,但非延迟字段已经存在。怎么说?
    猜你喜欢
    • 2021-05-29
    • 1970-01-01
    • 2013-07-23
    • 2013-02-23
    • 2015-01-02
    • 2021-11-07
    • 2021-12-27
    • 2013-11-02
    • 2013-01-14
    相关资源
    最近更新 更多