WedX - журнал о программировании и компьютерных науках

Сериализация JSON унаследованной модели Django

У меня есть следующие модели 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


Ответы:


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:

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

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

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

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

15.01.2013
  • Большое спасибо! Если кто-то попытается последовать этому предложению, скопируйте себе содержимое base.py, python.py и один из конкретных сериализаторов (json, xml и т. д.). Затем измените строку, как предложил @philipk в base.py, и переопределите цепочку наследования вплоть до конкретного сериализатора. Вы также можете добавить свой новый сериализатор в настройки, смотрите __init__.py (в пакете сериализаторов django) для более подробной информации. Еще раз спасибо @philipk, вы спасли мой день! :-) 17.06.2014

  • 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()
    
    07.02.2013

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

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

    17.07.2018
    Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]