Django继承模型的JSON序列化

4 投票
3 回答
2573 浏览
提问于 2025-04-15 22:54

我有以下的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)

如果需要的话,完整的模型文件可以在这里找到。

你可以看到,Company是ConfigurationItem的子类。

我想使用JSON序列化,方法是用django.core.serializers.serializer或者WadofStuff序列化器。

这两个序列化器都给我带来了同样的问题……

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

3 个回答

0

可能现在已经很晚了,但我还是分享一下我的解决方案,希望对你有帮助。我使用了另一个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))

你可以选择是否指定字段列表。我用我自己的一个模型试过,效果很好。唯一的不同是,输出结果中只会得到字段的值,而不是模型的其他信息。

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()
5

这可能是一个回答来得有点晚的情况,原提问者可能已经不需要了,但对下一个搜索的人来说可能会有用。

如果你需要更复杂的序列化功能,我帮不了你,但如果你只是想优雅地处理多表继承的问题,可以看看:django/core/serializers/base.py 文件里的 Serializer 基类。

serialize 方法中,有一行代码:

for field in concrete_model._meta.local_fields:

你可以通过修改这个类,把那一行替换成:

for field in concrete_model._meta.fields:

不过要注意一些问题,具体可以查看 Django Git 仓库里的提交记录 12716794db 和这两个问题:

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

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

简单来说,你在全局范围内这样做可能要小心,不过根据你的目标,覆盖这个行为可能是可以的。

撰写回答