【问题标题】:django: control json serializationdjango:控制json序列化
【发布时间】:2011-07-05 00:39:17
【问题描述】:

有没有办法控制 django 中的 json 序列化?下面的简单代码将在 json 中返回序列化对象:

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

json 看起来类似于:

[
    {
        "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
        }
    }
]

您可以看到它以一种您能够重新创建整个模型的方式对其进行序列化,您是否想在某个时候这样做 - 足够公平,但在我的情况下对于简单的 JS ajax 来说不是很方便:我想要把流量降到最低,让整个事情变得更清晰。

我所做的是创建了一个将对象传递给 .json 模板的视图,模板将执行类似的操作来生成“更好”的 json 输出:

[
{% 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 %}
]

这确实有效,并且输出要好得多(?):

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

但是,我的解决方案使用模板的速度太快(处理过程中的额外步骤和可能的性能影响)让我感到困扰,例如,如果我更新模型,则需要手动维护。

我认为 json 生成应该是模型的一部分(如果我错了,请纠正我)并使用本机 python-json 和 django 实现完成,但不知道如何使它剥离我没有的位不想。

还有一件事——即使我将其限制为一组要序列化的字段,它也会将 id 始终保留在元素容器之外,而是将其显示为“pk”。

【问题讨论】:

    标签: python django json serialization


    【解决方案1】:

    这真的很容易。快速示例:

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

    此视图将返回与以下 JSON 等效的内容:

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

    编辑:是的,Assaf Lavie 是对的,您的模板可能会产生无效的 JSON。

    【讨论】:

    • 这适用于数组,但我不认为 django 模式可以这样序列化。
    • 我认为他是在暗示您应该将所需模型对象中的字段复制到 JSON 可序列化类型中,例如 list 或 dict。 obj = Collection.objects.get(pk=1); simplejson.dumps(dict(urlName=obj.urlName, name=obj.name, sortOrder=obj.sortOder)。但就像在somebody else's answer 中一样,活塞可以为您完成这一步:)
    • 这或多或少适用于一些手动预处理 - 一些模型字段不能被 simplejson 序列化,我必须将它们转换为字符串:(
    【解决方案2】:

    我建议您使用the json library 对您的数据进行编码,而不仅仅是自己构建类似json 的字符串。一方面,上面的代码似乎没有正确处理转义。编写自己的序列化程序并没有什么好处(除了错误)。

    【讨论】:

      【解决方案3】:

      与其自己编写任何东西,不如让Piston 完成将 Django 模型序列化为 JSON 的工作。默认情况下,它只是序列化模型的字段,没有元数据。您可以轻松列出要包含或排除的字段(甚至是相关字段)。没有额外的模板,也很少查看代码。

      【讨论】:

      • 似乎不支持活塞 - 上次提交代码是 6 个月前,问题似乎没有得到答复/解决。
      • 公平。我一直在内部公司项目中使用它来成功地完成您需要的工作,但有时我不得不解决长期存在的错误。作为替代方案,如果您想要新的热点,请查看Tastypie
      • 有一个社区分叉正在进行中,并得到了活塞的作者 jesper 的批准。话虽如此,您应该只安装关闭一些开放错误的众多分叉中的一个。例如我的,bitbucket.org/wires/django-piston
      【解决方案4】:
      def view( request):
          m_all = list(model.objects.all().values())
      
          return HttpResponse(simplejson.dumps(m_all))
      

      这应该可以解决问题。 使用 values() 并转换为 list 应该会产生您想要的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-29
        • 2015-03-23
        • 2013-12-05
        • 2015-02-07
        • 2011-06-30
        • 2011-05-30
        • 2017-11-20
        • 2014-04-04
        相关资源
        最近更新 更多