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

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

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

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

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

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

Это то, что я возвращаю, обратите внимание, что внешние ключи (object\_type и Individual) являются просто идентификаторами связанных объектов.

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

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

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

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

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

 хотя не для целей RESTful. Мне удалось достичь того, что мне нужно, используя «полный» модуль сериализации, в моем случае[`Django Full Serializers`](https://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers), Это часть[wadofstuff](https://code.google.com/p/wadofstuff/) и распространяется под новой лицензией BSD.

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

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

Во-вторых, добавьте следующую настройку`settings.py` файл:

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

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

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

От[документация](https://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers#Backwards_Compatibility):

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

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

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



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



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

Тем не менее, посмотрите на[Официальный документ Джанго здесь](https://docs.djangoproject.com/en/1.10/topics/serialization/#natural-keys), Это действительно дает возможность использовать встроенный натуральный ключ. Кажется, что во встроенном сериализаторе django есть небольшая проблема с поддержкой использования ImageField как части естественного ключа. Но это может быть легко исправлено самим собой.



 я создал и недавно опубликовал[Джанго сериализуемой-модель](https://github.com/agilgur5/django-serializable-model) как легко расширяемый способ сериализации моделей, менеджеров и наборов запросов. Когда ваши модели расширяются`SerializableModel`они получают непоправимый`.serialize` метод, который имеет встроенную поддержку всех отношений.

Используя ваш пример, один развсе вовлеченные модели простираться`SerializableModel`:

призвание`.serialize` с отношениями в качестве аргументов библиотека будет рекурсировать по связанным объектам, вызывая`.serialize` на них тоже. Это возвращает словарь, который выглядит как:

Вы можете позвонить`json.dumps` в этом словаре, чтобы преобразовать его в JSON.

По умолчанию расширение`SerializableModel` также установит менеджер модели на`SerializableManager` (вы можете расширить его самостоятельно, если вы используете собственный менеджер), который использует`SerializableQuerySet`, Это означает, что вы можете позвонить`.serialize` на менеджере или в наборе запросов:

Это просто звонки`.serialize` для каждого объекта модели в наборе запросов, возвращая список словарей в том же формате, что и выше.

[Джанго сериализуемой-модель](https://github.com/agilgur5/django-serializable-model) также позволяет легко переопределять поведение по умолчанию для каждой модели, давая вам возможность делать такие вещи, как: добавлять белые или черные списки, применяемые к каждой модели`.serialize`всегда сериализуйте определенные объединения (чтобы вам не нужно было постоянно добавлять их в качестве аргументов) и многое другое!



 что этой теме уже много лет, но я делюсь своим решением для людей, которые все еще ищут ответ (во время моего поиска я оказался здесь).

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

В моем models.py у меня есть пользовательская функция (не в классе модели):

**Models.py**

Эта функция перебирает все поля в объекте models.Model, если предоставляется models.Model. Я вызываю функцию в модели следующим образом (для полноты картины, включая одну целую модель):

**тот же Models.py**

**Замечания:** Вложенные объекты JSON будут содержать только те поля, которые включены в**allowed\_fields** модели. Таким образом, не включая конфиденциальную информацию.

Чтобы в конечном итоге сгенерировать JSON, у меня есть следующее представление в моем views.py.

**views.py**

В конечном итоге это дало мне все вложенные детали, которые мне потребовались в ответе JSON. Хотя я не разделяю ответ JSON, так как этот едва читаемый.

Не стесняйтесь комментировать.