Атрибут instance
Атрибут instance класса ModelForm в Django используется для связывания формы с конкретным экземпляром модели. Это позволяет редактировать существующую запись, а не создавать новую. Если атрибут не указан, форма создает новый экземпляр модели при вызове метода save.
Синтаксис
class MyModelForm(ModelForm):
class Meta:
model = MyModel
fields = ['field1', 'field2']
# Создание формы для новой записи
form = MyModelForm()
# Создание формы для редактирования существующей записи
instance = MyModel.objects.get(pk=1)
form = MyModelForm(instance=instance)
Пример
Рассмотрим модель Article и форму для её редактирования:
from django.db import models
from django.forms import ModelForm
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
status = models.CharField(max_length=20)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'status']
Теперь получим статью для редактирования и создадим форму с указанием атрибута instance:
from myapp.forms import ArticleForm
from myapp.models import Article
# Получаем статью с id=1
article = Article.objects.get(id=1)
# Создаем форму для редактирования статьи
form = ArticleForm(instance=article)
# Выводим текущие значения полей
print(form.initial)
Результат выполнения кода:
{
"title": "Первая статья",
"content": "Текст содержимого статьи",
"status": "draft"
}
Пример
После отправки формы с изменениями, используем тот же атрибут для сохранения обновленных данных:
from myapp.forms import ArticleForm
from myapp.models import Article
# Получаем статью
article = Article.objects.get(id=1)
# Данные из POST-запроса с изменениями
post_data = {
'title': 'Обновленная статья',
'content': 'Новое содержимое',
'status': 'published'
}
# Создаем форму с instance и данными
form = ArticleForm(post_data, instance=article)
if form.is_valid():
# Сохраняем изменения в существующую запись
saved_article = form.save()
print(f"Статья обновлена: {saved_article.title}")
print(f"Статус: {saved_article.status}")
Результат выполнения кода:
"Статья обновлена: Обновленная статья"
"Статус: published"
Пример
Важно понимать разницу между созданием новой записи и редактированием существующей:
from myapp.forms import ArticleForm
from myapp.models import Article
# Создание новой записи
post_data = {
'title': 'Новая статья',
'content': 'Содержимое новой статьи',
'status': 'draft'
}
new_form = ArticleForm(post_data)
if new_form.is_valid():
# Создается новый объект в БД
new_article = new_form.save()
print(f"Создана новая статья с id={new_article.id}")
# Редактирование существующей записи
existing_article = Article.objects.get(id=1)
edit_form = ArticleForm(post_data, instance=existing_article)
if edit_form.is_valid():
# Обновляется существующий объект
updated_article = edit_form.save()
print(f"Обновлена статья с id={updated_article.id}")
Результат выполнения кода:
"Создана новая статья с id=5"
"Обновлена статья с id=1"