Сериализация объектов внешнего ключа в 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 не делает этого по умолчанию, но есть ли способ автоматически сериализовать объект и все связанные объекты? Любые советы или чтение будут высоко оценены.
Ответы
Ответ 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