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

Django rest framework модельные сериализаторы - читать вложенные, писать плоские

У меня есть ситуация, когда мой клиент пытается написать представление, которое включает в себя список fk

{
languages: [1]
last_name: "Beecher"
settings: 1
state: "NY"
}

Но, читая его, я хотел бы иметь вложенное представление, чтобы сократить круги в раундах

{
languages: [{id:1, created:2013-07-21T01:38:33.569Z, modified:2013-07-21T01:38:33.569Z, language:testing}]
last_name: "Beecher"
settings: {
created: "2013-07-20T22:04:17.998Z"
email_blog: false
email_booking_accepted_denied: false
email_booking_request: false
email_friend_joined: false
email_groups_added_network: false
email_new_review: false
email_news: false
email_upcoming_booking_remind: false
id: 1
mobile_booking_accepted_denied: false
mobile_booking_request: false
mobile_friend_joined: false
mobile_groups_added_network: false
mobile_new_review: false
mobile_upcoming_booking_remind: false
modified: "2013-07-20T22:04:18.000Z"
user: 1
}
state: "NY"
}

Чтение не представляет проблемы при использовании сериализатора модели и глубины = 1 - но попытка записи дает ошибку "ValueError (" экземпляр должен быть набором запросов или другим итерируемым с помощью множества = True ") При попытке проверить много связанных полей для iter

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

Есть ли что-то, чего я здесь совершенно не хватает? Похоже, что это должно быть простое изменение, но я могу получить только тот или иной рабочий

4b9b3361

Ответ 1

Благодаря предыдущим сообщениям, я пошел с аналогичным решением, основанным на get_serializer_class для этого.

Я также хотел иметь возможность изменять класс сериализатора в зависимости от метода.

Во-первых, я добавил атрибут класса представления со способами сопоставления сопоставления словарям в классы сериализатора.

 serializer_classes = {
     'GET': NestedSerializer,
     'POST': FlatSerializer
 }

Затем я определил mixin для использования там, где мне нужно это поведение.

class SwappableSerializerMixin(object):
    def get_serializer_class(self):
        try:
            return self.serializer_classes[self.request.method]
        except AttributeError:
            logger.debug('%(cls)s does not have the required serializer_classes'
                         'property' % {'cls': self.__class__.__name__})
            raise AttributeError
        except KeyError:
            logger.debug('request method %(method)s is not listed'
                         ' in %(cls)s serializer_classes' %
                         {'cls': self.__class__.__name__,
                          'method': self.request.method})
            # required if you don't include all the methods (option, etc) in your serializer_class
            return super(SwappableSerializerMixin, self).get_serializer_class() es

Ответ 2

У меня была такая же проблема, и похоже, что у многих ее тоже есть. Ответ Carlton Gibson на самом деле приводит меня к моему хакерскому решению. Я закончил использование ModelSerializer с настройкой глубины и создал следующий миксин для использования в представлениях.

class ReadNestedWriteFlatMixin(object):
    """
    Mixin that sets the depth of the serializer to 0 (flat) for writing operations.
    For all other operations it keeps the depth specified in the serializer_class
    """
    def get_serializer_class(self, *args, **kwargs):
        serializer_class = super(ReadNestedWriteFlatMixin, self).get_serializer_class(*args, **kwargs)
        if self.request.method in ['PATCH', 'POST', 'PUT']:
            serializer_class.Meta.depth = 0
        return serializer_class

Ответ 3

Простейшая вещь, которая возникает для меня, - это переопределить get_serializer_class() на вашем представлении для POST/PUT, чтобы вернуть модифицированный сериализатор, не указав параметр глубины, и используя PrimaryKeyRelatedField для вашего поля languages.