Django继承模型的JSON序列化

Posted

技术标签:

【中文标题】Django继承模型的JSON序列化【英文标题】:JSON Serialization of a Django inherited model 【发布时间】:2011-02-21 09:45:43 【问题描述】:

我有以下 Django 模型

class ConfigurationItem(models.Model):

    path = models.CharField('Path', max_length=1024)
    name = models.CharField('Name', max_length=1024, blank=True)
    description = models.CharField('Description', max_length=1024, blank=True)
    active = models.BooleanField('Active', default=True)
    is_leaf = models.BooleanField('Is a Leaf item', default=True)

class Location(ConfigurationItem):

    address = models.CharField(max_length=1024, blank=True)
    phoneNumber = models.CharField(max_length=255, blank=True)
    url = models.URLField(blank=True)
    read_acl = models.ManyToManyField(Group, default=None)
    write_acl = models.ManyToManyField(Group, default=None)
    alert_group= models.EmailField(blank=True)

如果有帮助,完整的模型文件是 here。

可以看到 Company 是 ConfigurationItem 的子类。

我正在尝试使用 django.core.serializers.serializer 或 WadofStuff 序列化器来使用 JSON 序列化。

两个序列化程序都给我同样的问题...

>>> from cmdb.models import *
>>> from django.core import serializers
>>> serializers.serialize('json', [ ConfigurationItem.objects.get(id=7)])
    '["pk": 7, "model": "cmdb.configurationitem", "fields": "is_leaf": true,    "extension_attribute_10": "", "name": "", "date_modified": "2010-05-19 14:42:53", "extension_attribute_11": false, "extension_attribute_5": "", "extension_attribute_2": "", "extension_attribute_3": "", "extension_attribute_1": "", "extension_attribute_6": "", "extension_attribute_7": "", "extension_attribute_4": "", "date_created": "2010-05-19 14:42:53", "active": true, "path": "/Locations/London", "extension_attribute_8": "", "extension_attribute_9": "", "description": ""]'
>>> serializers.serialize('json', [ Location.objects.get(id=7)])
    '["pk": 7, "model": "cmdb.location", "fields": "write_acl": [], "url": "", "phoneNumber": "", "address": "", "read_acl": [], "alert_group": ""]'
>>>

问题在于,序列化 Company 模型只会给我与该模型直接关联的字段,而不是来自它的父对象的字段。

有没有办法改变这种行为,或者我应该考虑构建一个对象字典并使用 simplejson 来格式化输出?

提前致谢

~sm

【问题讨论】:

【参考方案1】:

对于最初的发布者来说,答案可能来得太晚,但对于下一个 Google 员工来说可能会派上用场。

如果您需要更高级的序列化,我无法帮助您,但如果您只想优雅地处理多表继承,则可以查看:django/core/serializers/base.py Serializer 基类。

serialize 方法中有一行:

for field in concrete_model._meta.local_fields:

Monkeypatching 或覆盖该类并将该行替换为:

for field in concrete_model._meta.fields:

但有一些注意事项需要注意,请参阅 Django Git 存储库中的提交 12716794db 和这两个问题:

https://code.djangoproject.com/ticket/7350

https://code.djangoproject.com/ticket/7202

长话短说,您可能应该谨慎地在全局范围内执行此操作,但根据您的目标覆盖该行为可能没问题。

【讨论】:

非常感谢!如果有人尝试遵循此建议,请将base.pypython.py 的内容和具体的序列化程序之一(json、xml 等)复制给自己。然后按照@philipk 在base.py 中的建议更改该行,并一直覆盖继承链到具体的序列化程序。您还可以将新的序列化程序添加到设置中,查看__init__.py(在 django 序列化程序包中)了解更多详细信息。再次感谢@philipk,你拯救了我的一天! :-)【参考方案2】:

您需要一个自定义序列化器来支持继承的字段,因为 Django 的序列化器只会序列化本地字段。

我在处理这个问题时写了自己的,请随意复制:https://github.com/zmathew/django-backbone/blob/master/backbone/serializers.py

https://github.com/zmathew/django-backbone/blob/351fc75797bc3c75d2aa5c582089eb39ebb6f19a/backbone/serializers.py

为了单独使用它,你需要做:

serializer = AllFieldsSerializer()
serializer.serialize(queryset, fields=fields)
print serializer.getvalue()

【讨论】:

【参考方案3】:

也许已经很晚了,但我给出了我的解决方案,以防它可能有用。我使用了另一个可以解决问题的 Django 库:

from django.forms.models import model_to_dict

model_to_dict(Location.objects.get(id=7), fields = ['name', 'address', 'phoneNumber'])
model_to_dict(Location.objects.get(id=7))

您可以指定或不指定字段列表。我试过我的一个模型,它对我来说很好用。唯一的区别是在输出中你将只得到字段值,而不是模型信息。

【讨论】:

以上是关于Django继承模型的JSON序列化的主要内容,如果未能解决你的问题,请参考以下文章

JSON 使用 simplejson 序列化 Django 模型

如何 JSON 序列化 Django 模型的 __dict__?

Django Rest API:序列化模型时如何摆脱 json 中的“UUID”?

序列化多个模型并在一个 json 响应中发送全部 django rest 框架

如何将 django/python 中的模型对象列表序列化为 JSON

Django - 使用模型和数据序列化复杂的上下文结构