Сериализация JSON унаследованной модели Django - PullRequest
4 голосов
/ 19 мая 2010

У меня есть следующие модели 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 для форматирования вывода?

Заранее спасибо

~ см

Ответы [ 3 ]

4 голосов
/ 15 января 2013

Это один из тех случаев, когда ответ может прийти слишком поздно для оригинального плаката, но может пригодиться для следующего Гуглера.

Если вам нужна значительно более продвинутая сериализация, я не могу вам помочь, но если вам нужна только изящная обработка многотабличного наследования, вам стоит поискать: django/core/serializers/base.py базовый класс Serializer.

В методе serialize есть строка:

for field in concrete_model._meta.local_fields:

Monkeypatching или переопределение этого класса и замена этой строки на:

for field in concrete_model._meta.fields:

Однако следует помнить о некоторых предостережениях, см. Commit 12716794db в репозитории Django Git и следующие две проблемы:

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

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

Короче говоря, вам, вероятно, следует проявлять осторожность, делая это в глобальном масштабе, хотя в зависимости от вашей цели может быть отменено такое поведение.

2 голосов
/ 07 февраля 2013

Вам потребуется специальный сериализатор для поддержки унаследованных полей, поскольку сериализатор 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()
0 голосов
/ 17 июля 2018

Может быть, уже очень поздно, но я даю свое решение, на случай, если оно окажется полезным. Я использовал другую библиотеку 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))

Вы можете указать или нет список полей. Я пытался с моей моделью, и она работала нормально для меня. Разница лишь в том, что в выходных данных вы получите только значение поля, а не информацию о модели.

...