Django 5 для начинающих

Прогресс по курсу:  9/1004

8.3 Сериализаторы
1 из 2 шагов пройден
0 из 3 баллов  получено

Что такое сериализатор в Django REST Framework?

Сериализаторы позволяют преобразовывать сложные данные, такие как наборы запросов querysets и экземпляров моделей, в собственные типы данных Python, которые затем можно легко преобразовать в форматы JSON, XML или в другие типы содержимого. Сериализаторы также обеспечивают десериализацию, позволяя преобразовывать проанализированные данные обратно в сложные типы, после предварительной проверки входящих данных.

Сериализаторы в DRF работают очень похоже на классы Django Form и ModelForm.

Давайте рассмотрим следующий код. Чтобы создать базовый сериализатор, необходимо импортировать класс сериализаторов из rest_framework и определить поля для сериализатора так же, как при создании формы или модели в Django.

from rest_framework import serializers
 
# create a serializer
class CommentSerializer(serializers.Serializer):
    # initialize fields
    email = serializers.EmailField()
    content = serializers.CharField(max_length = 200)
    created = serializers.DateTimeField()

Теперь можно использовать CommentSerializer для сериализации комментария или списка комментариев. Опять же, использование класса Serializer очень похоже на использование класса Form.

Сериализатор CommentSerializer, который мы рассматриваем, отвечает сейчас только за конвертацию данных в JSON-формат и обратно. Однако, хорошей практикой считается, когда здесь же в сериализаторе определяется алгоритм сохранения или изменения данных в БД. Этот функционал лучше создать в сериализаторе. Для этого каждый класс сериализаторов имеет два специальных метода:

  • create(self, validated_data) – для добавления (создания) записи (данных);
  • update(self, instance, validated_data) – для изменения данных (записи).

То есть чтобы создать эти функции в нашем сериализаторе необходимо создать эти функции.

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

    def create(self, validated_data):
        return Comment(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        return instance

Более подробно о работе сериализатора вы можете почитать на странице документации.

Но также Django REST Framework предлагает класс Serializer, который предоставляет вам мощный, универсальный способ управления выводом ваших ответов, а также класс ModelSerializer, который предоставляет полезный ярлык для создания сериализаторов, проектов с экземплярами моделей и наборами исходных файлов.

Класс ModelSerializer аналогичен обычному классу Serializer, за исключением того, что: 

  • Он автоматически сгенерирует для вас набор полей на основе модели.
  • Он автоматически сгенерирует валидаторы для сериализатора, такие как валидаторы unique_together.
  • Он включает простые реализации по умолчанию .create() и .update().

Давайте создадим его, для этого в папке blog_api создадим файл serializers.py следующего содержания:

from rest_framework import serializers
from blog.models import Post


class PostSerializer(serializers.ModelSerializer):
    class Meta:
        fields = (
            "id",
            "author",
            "title",
            "body",
            "created",
        )
        model = Post

Укажем в качестве базового класса ModelSerializer для нашего сериализатора PostSerializer и тогда уже нет необходимости вручную прописывать атрибуты для связи с соответствующими атрибутами модели Post, а также методы create() и update(). А вместо всего этого пропишем вложенный класс Meta.


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Здравствуйте, я давно думал о Django Rest Framework, и я бы хотел узнать будут ли использоваться старые приемы в курсе для продвинутых, мне просто кажется что писать надо используя преимущественно только DRF. Это тема мне очень интересна, ведь она начинает раскрывать для меня то, как данные попадают в GraphQL и в следствии в фронт(Vue.js например), а это по сути современная архитектура разработки веб приложений.

Изменен Шамбер Егор

@Шамбер_Егор, Во втором курсе не будет DRF совсем, там мы немного другие технологии используем. Под DRF планируем отдельный курс, но пока трудно сказать когда он будет.

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

1) представлений

2) точно свойств? возможно имелось в виду файлов?

@Виктор_Русинович, исправил, спасибо.

Вообще не понял этот шаг:

1) где мы пишем сериализатор? в views.py? 
2) Что такое return Comment(**validated_data)? И почему у меня в pycharm'е Commentподчеркивается красным?
Очень хотелось бы больше конкретики и расписывание даже вроде тупых мест. Тема важная очень

@Кирилл_Смирнов,

Смотрите, на основе CommentSerializer мы рассмотрели создание простейшего сериализатора и создание для него методов create и update. Данный код нужно просто понять, как это работает изнутри. А для нашего блога мы уже пишем PostSerializer на основе базового класса ModelSerializer. Сериализаторы пишутся в serializers.py

return Comment(**validated_data)

В данной строке мы передаем классу Comment распакованные пары ключей и значений. Подробнее можете почитать https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/

@Илья_Перминов, то есть этот класс тоже в serializers.py добавлять надо?

@Кирилл_Смирнов, да, но в проект блога мы его не добавляем. Для блога мы пишем serializers.py следующего содержания:

from rest_framework import serializers
from blog.models import Post


class PostSerializer(serializers.ModelSerializer):
    class Meta:
        fields = (
            "id",
            "author",
            "title",
            "body",
            "created",
        )
        model = Post

На примере CommentSerializer мы только рассмотрели как работают сериализаторы. А для блога мы уже написали сериализатор постов(PostSerializer) наследуясь от базовых классов, чтобы упростить данный код, так как мы не используем никакую более сложную логику. Сериализаторы это вообще один из самых сложных этапов понимания DRF, и для данного курса мы считаем что нужно изначально понять взаимодействие внутри фреймворка, а лишь потом усложнение кода.