← Назад к вопросам

Чем отличается Form от ModelForm?

1.0 Junior🔥 161 комментариев
#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Form vs ModelForm в Django

Основное отличие

Form — это обычная форма для работы с произвольными данными, которые не привязаны к моделям. ModelForm — это специальный тип формы, которая автоматически генерируется на основе Django модели и напрямую работает с экземплярами моделей.

Ключевые различия

1. Определение

Form определяется вручную с перечислением всех полей:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)
    phone = forms.CharField(required=False)

ModelForm автоматически создаёт поля на основе модели:

from django import forms
from .models import Article

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ["title", "content", "author"]

2. Привязка к модели

Form — никак не связан с моделью. Это просто контейнер для валидации данных:

form = ContactForm(data=request.POST)
if form.is_valid():
    # Данные валидны, но это ещё не объект модели
    email = form.cleaned_data["email"]
    # Нужно вручную создавать объект
    contact = Contact.objects.create(
        name=form.cleaned_data["name"],
        email=form.cleaned_data["email"]
    )

ModelForm автоматически работает с моделью:

form = ArticleForm(data=request.POST)
if form.is_valid():
    # Метод save() автоматически создаёт/обновляет объект модели
    article = form.save()
    # Или с коммитом в БД
    article = form.save(commit=True)

3. Валидация

Form проверяет только типы и формат полей:

class ContactForm(forms.Form):
    email = forms.EmailField()  # Валидирует только email формат
    age = forms.IntegerField(min_value=0, max_value=150)

ModelForm использует валидаторы из модели + форму:

# В модели
class Article(models.Model):
    title = models.CharField(max_length=200, unique=True)
    content = models.TextField(validators=[MinLengthValidator(10)])
    published = models.BooleanField(default=False)

# ModelForm автоматически применит эти ограничения
class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ["title", "content", "published"]

4. Сохранение данных

Form требует ручного создания объекта в БД:

if form.is_valid():
    obj = MyModel.objects.create(**form.cleaned_data)

ModelForm имеет встроенный метод save():

if form.is_valid():
    obj = form.save()  # Автоматически создаст или обновит запись

Кроме того, можно отложить сохранение:

obj = form.save(commit=False)  # Создаст объект, но не сохранит в БД
obj.author = request.user  # Можно модифицировать
obj.save()  # Теперь сохраняет

5. Изменение существующих объектов

Form при работе с существующим объектом требует ручного обновления:

obj = MyModel.objects.get(id=1)
form = ContactForm(request.POST)
if form.is_valid():
    obj.name = form.cleaned_data["name"]
    obj.email = form.cleaned_data["email"]
    obj.save()

ModelForm автоматически определяет, нужно ли создавать или обновлять:

obj = Article.objects.get(id=1)
form = ArticleForm(request.POST, instance=obj)
if form.is_valid():
    form.save()  # Обновит существующий объект

Когда использовать что?

Используй Form, когда:

  • Данные не привязаны к модели (контактная форма, поиск)
  • Нужна сложная логика валидации
  • Форма работает с несколькими моделями одновременно
  • Нужна полная гибкость

Используй ModelForm, когда:

  • Форма представляет данные модели (Create/Update операции)
  • Нужна быстрая разработка (CRUD интерфейсы)
  • Хочешь использовать валидаторы модели
  • Нужна интеграция с админкой Django

Практический пример

# Модель
class BlogPost(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(unique=True)
    content = models.TextField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    published = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

# ModelForm для CRUD
class BlogPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ["title", "slug", "content", "category", "published"]

# Обычная Form для фильтрации
class BlogFilterForm(forms.Form):
    search = forms.CharField(required=False)
    category = forms.ModelChoiceField(queryset=Category.objects.all(), required=False)
    published_only = forms.BooleanField(required=False)

Вывод: Form — инструмент для валидации данных, ModelForm — инструмент для работы с моделями. ModelForm построен на базе Form и добавляет интеграцию с ORM.

Чем отличается Form от ModelForm? | PrepBro