Атрибут instance

Атрибут instance класса ModelForm в Django используется для связывания формы с конкретным экземпляром модели. Это позволяет редактировать существующую запись, а не создавать новую. Если атрибут не указан, форма создает новый экземпляр модели при вызове метода save.

Синтаксис

pythonclass MyModelForm(ModelForm):
  class Meta:
    model = MyModel
    fields = ['field1', 'field2']

# Создание формы для новой записи
form = MyModelForm()

# Создание формы для редактирования существующей записи
instance = MyModel.objects.get(pk=1)
form = MyModelForm(instance=instance)

Пример

Рассмотрим модель Article и форму для её редактирования:

pythonfrom 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:

pythonfrom myapp.forms import ArticleForm
from myapp.models import Article

# Получаем статью с id=1
article = Article.objects.get(id=1)

# Создаем форму для редактирования статьи
form = ArticleForm(instance=article)

# Выводим текущие значения полей
print(form.initial)

Результат выполнения кода:

python{
  "title": "Первая статья",
  "content": "Текст содержимого статьи",
  "status": "draft"
}

Пример

После отправки формы с изменениями, используем тот же атрибут для сохранения обновленных данных:

pythonfrom 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}")

Результат выполнения кода:

python"Статья обновлена: Обновленная статья"
"Статус: published"

Пример

Важно понимать разницу между созданием новой записи и редактированием существующей:

pythonfrom 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}")

Результат выполнения кода:

python"Создана новая статья с id=5"
"Обновлена статья с id=1"

Смотрите также

  • класс ModelForm,
    который используется для создания форм на основе моделей
  • метод save,
    который сохраняет данные формы в базу данных
  • класс Form,
    который является базовым классом для создания форм
  • метод is_valid,
    который выполняет валидацию данных в форме