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

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

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

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

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

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

3 Solutions collect form web for “Сериализация объектов внешнего ключа в Django”

У меня было аналогичное требование, но не для целей 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 – использовать имя полей, образующих отношение, а не имена соответствующих моделей.

Предостережение

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

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

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

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

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

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

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

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

Python - лучший язык программирования в мире.