Короткий ответ
Django Form ориентирован на обработку данных HTML-формы и рендеринг виджетов/ошибок в шаблоне (server-rendered страницы), тогда как DRF Serializer ориентирован на (де)сериализацию структурированных данных (обычно JSON) для API; в одном проекте оба уместны, если часть приложения — классические серверные страницы, а часть — JSON API.
Как это работает подробнее
Form/ModelForm тесно интегрированы с Django-шаблонами: умеют рендерить HTML-поля, показывать ошибки рядом с полем, работать с multipart/form-data для файлов в контексте обычной веб-страницы. Serializer/ModelSerializer не привязаны к HTML: они описывают структуру данных для API, умеют валидировать и преобразовывать вложенные структуры, списки и т. п., без понятия «виджет».
Пример кода
example.py
# Для HTML-страницы
from django import forms
class RegistrationForm(forms.Form):
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput, min_length=8)
# Для JSON API (DRF)
from rest_framework import serializers
class RegistrationSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField(min_length=8, write_only=True)
# Общую бизнес-проверку (например, "email не занят") имеет смысл
# вынести в отдельную функцию/сервис и вызывать из обоих мест.Что использовать на практике
- Практика. В проекте с админкой/классическими страницами (например, регистрация через HTML-форму) и одновременно с мобильным приложением, которое ходит в JSON API, естественно иметь
RegistrationFormдля веб-страницы иRegistrationSerializerдля API — они могут частично пересекаться по бизнес-правилам, но решают разные задачи представления.
Подводные камни
- Риск. Пытаются «подружить»
Formнапрямую с API, передавая в него JSON как если бы это были данные формы, что приводит к неожиданному поведению с типами и списками; дублируют валидационную логику в обоих местах без выделения общей функции/доменного слоя, из-за чего правила расходятся при изменении требований.