> * Django Form — это инструмент для валидации входных данных HTML. > * DRF Serializer — инструмент для валидации и преобразования данных JSON API. > * Оба инструмента имеют очень схожие потоки обработки `is_valid()`, валидированных данных и ошибок. > * ModelForm и ModelSerializer также похожи по структуре автоматического создания полей на основе модели и сохранения данных. *** ## Сходства Django Form и DRF Serializer Мы собрали информацию о сходствах двух «стражей», которые надежно (а иногда и доставляя головную боль) защищают нас при работе с [[Django]]: [[Django Form]] и **DRF ([[Django REST Framework]]) Serializer**. Эти два инструмента, хотя и работают на разных «сценах» (веб-страницы против API), поразительно похожи по своей сути и структуре: оба они безопасно проверяют внешние данные перед их вводом и красиво упаковывают внутренние данные перед их выводом. ![Символическое изображение сериализатора и формы](/media/whitedec/blog_img/bhqorJyY.webp) *** ## 1. Сравнение ролей с первого взгляда Проще говоря, их можно сравнить с «охранниками и администраторами» на входе в универмаг. * **Django Form:** Работает в мире **HTML веб-страниц**. Проверяет правильность данных (Form Data), введенных пользователем в браузере, и если есть ошибки, любезно отображает на экране сообщение «Пожалуйста, введите данные снова». * **DRF Serializer:** Работает преимущественно в мире **API**, где происходит обмен **JSON**. Преобразует JSON-данные, отправленные мобильными приложениями или фронтендом (React, Vue и т.д.), в объекты Python и, наоборот, красиво упаковывает (сериализует) данные из базы данных в JSON. | Функция | Django Form (ориентирован на веб-страницы) | DRF Serializer (ориентирован на API) | | --- | ----------------------------------- | ---------------------------------- | | **Вход (Input)** | HTML Form -> словарь Python (`cleaned_data`) | Строка JSON -> словарь Python (`validated_data`) | | **Валидация данных** | Вызов `is_valid()` | Вызов `is_valid()` | | **Выход (Output)** | Объект Python -> рендеринг в HTML-теги (``) | Объект Python -> преобразование в строку JSON (сериализация) | *** ## 2. Почему они так похожи? Три структурных сходства Разработчики DRF были настолько впечатлены превосходной структурой Django Form, что практически полностью скопировали ее при создании Serializer. Поэтому структура кода и способы использования этих инструментов похожи как у близнецов. ### ① Одинаковый способ определения полей Способ определения формата входящих данных абсолютно идентичен. * **Django Form:** ```python from django import forms class UserForm(forms.Form): username = forms.CharField(max_length=100) email = forms.EmailField() age = forms.IntegerField() ``` * **DRF Serializer:** ```python from rest_framework import serializers class UserSerializer(serializers.Serializer): username = serializers.CharField(max_length=100) email = serializers.EmailField() age = serializers.IntegerField() ``` > За исключением того, что `forms` изменился на `serializers`, логика объявления полей абсолютно одинакова. ### ② Одинаковый подход к валидации и доступу к данным Процесс проверки безопасности данных и доступа к валидированным данным совпадает. 1. **Проверка валидности:** Оба метода вызывают `if form.is_valid():` или `if serializer.is_valid():` после передачи данных. 2. **Доступ к прошедшим валидацию данным:** Чистые, валидированные данные сохраняются в словаре `form.cleaned_data` для Form и `serializer.validated_data` для Serializer. Названия немного отличаются, но функционал идентичен. 3. **Проверка ошибок:** В случае неудачной валидации `form.errors` или `serializer.errors` предоставляют сообщения об ошибках в виде словаря, указывая, что именно пошло не так. ### ③ Интеграция с Model (ModelForm против ModelSerializer) Суть Django заключается в интеграции с базой данных (Model). Оба инструмента имеют «чит-код» классы, которые автоматически создают поля на основе модели. * **Django ModelForm:** ```python class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = ['title', 'content'] ``` * **DRF ModelSerializer:** ```python class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel fields = ['title', 'content'] ``` > Синтаксис использования внутреннего класса `Meta` для указания модели и полей, которые будут использоваться, также поразительно идентичен. Благодаря этому, вызов метода `save()` приводит к автоматическому созданию (`create`) или изменению (`update`) данных в базе данных. *** ## В заключение * **Django Form** выступает в роли переводчика **между HTML и Python**, осуществляя валидацию данных. * **DRF Serializer** выступает в роли переводчика **между JSON и Python**, осуществляя валидацию данных. Если вы ранее работали с Django Form, то можете считать DRF Serializer «Формой, которая работает с JSON вместо HTML!» — и будете правы более чем на 90%. И наоборот, если вы сначала освоили Serializer, то Form также будет легко понять. Однако, я полагаю, что многие бэкенд-разработчики, несмотря на значительное сходство этих двух инструментов, чувствуют себя комфортно с Serializer, но испытывают некоторое неудобство с Form, которая является его основой. Я сам отношусь к их числу. Задумывались ли вы когда-нибудь, почему возникает такое чувство? В следующей части мы поговорим о причинах, по которым Django Form, будучи похожим на Serializer, вызывает внутренний дискомфорт при использовании. Если эта статья оказалась полезной, поставьте лайк и ждите следующей публикации!