Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# 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.