Метод get_form

Метод get_form класса ModelAdmin используется для возврата класса формы, который будет применяться при создании и редактировании объектов модели в административной панели. Этот метод вызывается для каждой операции добавления или изменения записи и позволяет динамически изменять поля формы, их виджеты или валидацию в зависимости от контекста.

Метод принимает два параметра: request - объект HTTP-запроса, и obj - экземпляр модели, который редактируется (или None при создании нового объекта). Возвращает класс формы, который должен быть наследником ModelForm.

Синтаксис

pythonclass MyModelAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):
    # Custom logic here
    return super().get_form(request, obj, **kwargs)

Пример

Рассмотрим базовый пример использования метода для динамического изменения формы в зависимости от прав пользователя:

pythonfrom django.contrib import admin
from django import forms
from myapp.models import Article

class ArticleAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):
    form = super().get_form(request, obj, **kwargs)

    # Hide 'status' field for non-staff users
    if not request.user.is_superuser:
      if 'status' in form.base_fields:
        form.base_fields['status'].widget = forms.HiddenInput()

    return form

Пример

Используем метод для динамического добавления полей в форму при создании нового объекта:

pythonfrom django.contrib import admin
from django import forms
from myapp.models import Article

class ArticleAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):
    form = super().get_form(request, obj, **kwargs)

    # Add extra field when creating new object
    if obj is None:
      form.base_fields['creator'] = forms.CharField(
        label='Creator',
        max_length=100,
        initial=request.user.username
      )

    return form

Пример

Рассмотрим более сложный пример с использованием кастомной формы и динамической настройки в зависимости от типа объекта:

pythonfrom django.contrib import admin
from django import forms
from myapp.models import Article

class CustomArticleForm(forms.ModelForm):
  class Meta:
    model = Article
    fields = ['title', 'content', 'status']

class ArticleAdmin(admin.ModelAdmin):
  form = CustomArticleForm

  def get_form(self, request, obj=None, **kwargs):
    form = super().get_form(request, obj, **kwargs)

    # Change widget based on object status
    if obj and obj.status == 'draft':
      form.base_fields['content'].widget = forms.Textarea(
        attrs={'rows': 10, 'class': 'draft-editor'}
      )

    return form

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

python"Form class returned: CustomArticleForm"
"Widget for content field modified for draft articles"

Пример

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

pythonfrom django.contrib import admin
from django import forms
from myapp.models import Article

class ArticleAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):
    form = super().get_form(request, obj, **kwargs)

    # Add 'category' field only for new objects
    if obj is None:
      form.base_fields['category'] = forms.ChoiceField(
        choices=[('tech', 'Tech'), ('science', 'Science')]
      )

    return form

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

  • атрибут form,
    который задает форму по умолчанию
  • метод save_model,
    который вызывается при сохранении объекта в базе данных
  • атрибут fields,
    который определяет порядок и набор отображаемых полей
  • атрибут readonly_fields,
    который делает поля доступными только для чтения