Как сериализовать модели Django с вложенными объектами (Django Rest Framework)

Если у меня есть два сериализатора, где один вложен, как настроить метод restore_object? Например, если у меня определены следующие сериализаторы, как определить поле объекта restore для моего вложенного сериализатора? Из документации не видно, как обращаться с таким случаем.

class UserSerializer(serializers.Serializer):
    first_name = serializers.CharField(required=True, max_length=30)
    last_name = serializers.CharField(required=True, max_length=30)
    username = serializers.CharField(required=True, max_length=30)
    email = serializers.EmailField(required=True)
    password = serializers.CharField(required=True)

    def restore_object(self, attrs, instance=None):
        if instance:
            instance.first_name = attrs.get('first_name', instance.first_name)
            instance.last_name = attrs.get('last_name', instance.last_name)
            instance.email = attrs.get('email', instance.email)
            instance.password = attrs.get('password', instance.password)

class UserProfileSerializer(serializers.Serializer):
    user = UserSerializer()
    bio = serializers.CharField()
    def restore_object(self, attrs, instance=None):
        if instance:
            instance.bio = attrs.get('bio', instance.bio)
            instance.user = ?????

1 ответов


важная заметка на полях: похоже, вы используете старую методологию пользователя / профиля. С Django 1.5 нет разделения пользователя по умолчанию и ваших пользовательских моделей профилей. Вы должны создать свою собственную модель пользователя и использовать ее вместо модели по умолчанию: Пользовательский Профиль Пользователя @ Django Docs

сериализация

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

from django.core import serializers
serialized_data = serializers.serialize("json", myInstance)

или сериализовать более одного объекта:

serialized_data = serializers.serialize("json", User.objects.all())

внешние ключи и отношения m2m затем сохраняются в массиве идентификаторов.

если вы хотите только подмножество полей для сериализации:

serialized_data = serializers.serialize("json", myUserInstance, fields=('first_name ','last_name ','email ','password '))

чтобы сохранить профиль пользователя, вы просто напишите:

serialized_data = serializers.serialize("json", myUserProfileInstance)

идентификатор пользователя сохраняется в сериализованном данные и выглядит так:

{
    "pk": 1,
    "model": "profile.UserProfile",
    "fields": {
        "bio": "self-taught couch potato",
        "user": 1
    }
}

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

class UserManager(models.Manager):
    def get_by_natural_key(self, first_name, last_name):
        return self.get(first_name=first_name, last_name=last_name)

class User(models.Model):
    objects = UserManager()

    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    ...

    def natural_key(self):
        return (self.first_name, self.last_name)

    class Meta:
        unique_together = (('first_name', 'last_name'),)

при сериализации с помощью естественных ключей вам нужно добавить :

serialized_data = serializers.serialize("json", myUserProfileInstance, use_natural_keys=True)

что приводит к следующему выводу:

{
    "pk": 2,
    "model": "profile.UserProfile",
    "fields": {
        "bio": "time-traveling smartass",
        "user": ["Dr.", "Who"]
    }
}

десериализации

десериализация и сбережений как:

for deserialized_object in serializers.deserialize("json", serialized_data):
    deserialized_object.save()

больше информацию можно найти в документах Django:сериализация объектов Django