Метод get_form
Метод get_form класса ModelAdmin используется
для возврата класса формы, который будет применяться
при создании и редактировании объектов модели
в административной панели. Этот метод вызывается
для каждой операции добавления или изменения записи
и позволяет динамически изменять поля формы,
их виджеты или валидацию в зависимости от контекста.
Метод принимает два параметра: request - объект
HTTP-запроса, и obj - экземпляр модели, который
редактируется (или None при создании нового объекта).
Возвращает класс формы, который должен быть наследником
ModelForm.
Синтаксис
class MyModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
# Custom logic here
return super().get_form(request, obj, **kwargs)
Пример
Рассмотрим базовый пример использования метода для динамического изменения формы в зависимости от прав пользователя:
from 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
Пример
Используем метод для динамического добавления полей в форму при создании нового объекта:
from 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
Пример
Рассмотрим более сложный пример с использованием кастомной формы и динамической настройки в зависимости от типа объекта:
from 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
Результат выполнения кода:
"Form class returned: CustomArticleForm"
"Widget for content field modified for draft articles"
Пример
Метод также позволяет динамически изменять набор полей формы в зависимости от значения других полей:
from 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,
который делает поля доступными только для чтения