Подтвердить что ты не робот

Сериализация объектов внешнего ключа в Django

Я работаю над разработкой некоторых RESTful сервисов в Django для использования с приложениями Flash и Android.

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

У меня есть такая модель:

class Artifact( models.Model ):
    name                = models.CharField( max_length = 255 )
    year_of_origin      = models.IntegerField( max_length = 4, blank = True, null = True )
    object_type         = models.ForeignKey( ObjectType, blank = True, null = True )
    individual          = models.ForeignKey( Individual, blank = True, null = True )
    notes               = models.TextField( blank = True, null = True )

Затем я выполнил бы запрос по этой модели, используя этот параметр, используя select_related(), чтобы убедиться, что отношения с внешним ключом соблюдены:

artifact = Artifact.objects.select_related().get(pk=pk)

Как только у меня есть объект, я сериализую его и передаю обратно в мое представление:

serializers.serialize( "json", [ artifact ] )

Это то, что я верну, обратите внимание, что внешние ключи (object_type и individual) являются просто идентификатором связанных объектов.

[
      {
            pk: 1
            model: "artifacts.artifact"
            fields: {
                year_of_origin: 2010
                name: "Dummy Title"
                notes: ""
                object_type: 1
                individual: 1
            }
      }
]

Это здорово, но я надеялся, что при использовании select_related() было бы автоматически заполнять поля внешнего ключа связанным объектом, а не только идентификатором объекта.

Я недавно конвертирую в Django, но приложил немало времени для разработки CakePHP.

Что мне действительно нравится в Cake ORM, так это то, что он будет следовать за отношениями и создавать вложенные объекты по умолчанию, с возможностью развязать отношения при вызове вашего запроса.

Это упростило абстрактные сервисы таким образом, чтобы не требовать вмешательства в каждом конкретном случае.

Я вижу, что Django не делает этого по умолчанию, но есть ли способ автоматически сериализовать объект и все связанные объекты? Любые советы или чтение будут высоко оценены.

4b9b3361

Ответ 1

У меня было аналогичное требование, но не для целей RESTful. Я смог добиться того, что мне нужно, используя "полный" модуль сериализации, в моем случае Django Full Serializers. Это часть wadofstuff и распространяется по новой лицензии BSD.

Wadofstuff делает это довольно легко. Напр. в вашем случае вам нужно будет сделать следующее:

Сначала установите wadofstuff.

Во-вторых, добавьте следующий параметр в ваш файл settings.py:

SERIALIZATION_MODULES = {
    'json': 'wadofstuff.django.serializers.json'
}

В-третьих, немного измените код, используемый для сериализации:

artifact = Artifact.objects.select_related().get(pk=pk)
serializers.serialize( "json", [ artifact ], indent = 4, 
    relations = ('object_type', 'individual',))

Ключевым изменением является параметр ключевого слова relations. Единственный (младший) getcha - использовать имя полей, образующих отношение, а не имена соответствующих моделей.

Caveat

В документации :

Сериализаторы Wad of Stuff на 100% совместимы с сериализаторами Django при сериализации модели. При десериализации потока данных класс Deserializer в настоящее время работает только с сериализованными данными, возвращаемыми стандартными сериализаторами Django.

(добавлен акцент)

Надеюсь, что это поможет.

Ответ 2

UPDATE: На самом деле решение Manoj немного устарело, сериализатор Wad of Stuff в течение некоторого времени не обновлялся, и когда я это пробовал, похоже, что он больше не поддерживает Django 1.6.

Однако посмотрите официальный dang Django здесь. Это действительно помогает в использовании встроенного естественного ключа. Похоже, что встроенный сериализатор django имеет небольшую проблему, поддерживая использование ImageField как части естественного ключа. Но это может быть легко исправлено самим собой.

Ответ 3

Дополнительную информацию об этом билете вы можете найти:

Разрешить глубокую сериализацию, указав глубину для соответствия https://code.djangoproject.com/ticket/4656