Как отфильтровать дополнительные контекстные данные из одного сериализатора при использовании в другом? - PullRequest
0 голосов
/ 15 марта 2019

С django rest framework у меня есть два сериализатора для двух разных моделей.Допустим, модели - это Автор и Книга.Модель автора имеет поля: имя, адрес, телефон, адрес электронной почты, описание и create_at, в то время как книга имеет поля: имя, имя_публикатора, жанр, описание, creat_at и author (внешний ключ для модели Author).

СейчасУ меня есть сериализаторы, определенные для Автора и Книги:

class BookSerializer(serializers.Serializer):

    class Meta:
        model = Book
        exclude = ['created_at']

class AuthorSerializer(serializers.Serializer):
    books = BookSerializer(many=True,required=False,null=True)        

    class Meta: 
        model = Author
        exclude = ['created_at']

Текущая схема дает возврат сериализатора Книги, например, как:

{
    "id":1,
    "name":"Book_name",
    "publisher_name":"Publisher",
    "genre":"g",
    "description":"Book description",
    "author":1
}

В то время как возвращение authorserializer является:

{
    "id":1,
    "address":"Address",
    "phone":9812312312,
    "email":"email@email.c",
    "description":"this is description",
    "books": [
            {
                "id":1,
                "name":"Book_name",
                "publisher_name":"Publisher",
                "genre":"g",
                "description":"Book description",
                "author":1
            }
            ]
    }

Дело в том, что я не хочу всех подробностей в книгах возврата для Authorserializer, и хочу исключить описание и жанр.Как это сделать?

Ответы [ 2 ]

0 голосов
/ 15 марта 2019

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

class InlineModelSerializer(serializers.ModelSerializer):
    """
    Used to dynamically create simple model serializers inline,
    mostly nested as fields in other serializers
    """

    def __init__(self, fields, model, **kwargs):
        """
        :param fields: The fields to be included
        :param model: The model class for the serializer
        :type fields: tuple
        """
        self.Meta = type('Meta', (), {'model': model, 'fields': fields})
        super(InlineModelSerializer, self).__init__(**kwargs)


Вы можетезатем используйте его в AuthorSerializer или в любом другом месте, например:

books = InlineModelSerializer(
    model=Book,
    fields=('id', 'name'),
    many=True,
    required=False,
    allow_null=True
)

Конечно, это не будет работать, если вам придется переопределить метод во вложенном сериализаторе, так что это в основном для простых случаев использования ине для сложных записываемых вложенных сериализаторов.

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

0 голосов
/ 15 марта 2019

Вам нужно будет создать новый сериализатор для книг. Возможно, назовите это BookSummarySerializer:

class BookSummarySerializer(serializers.Serializer):

    class Meta:
        model = Book
        exclude = ['created_at', 'description', 'genre']

class AuthorSerializer(serializers.Serializer):
    books = BookSummarySerializer(many=True,required=False,null=True)        

    class Meta: 
        model = Author
        exclude = ['created_at']
...