Сайт администрирования Django
Одна из самых мощных возможностей Django — автоматический интерфейс администрирования. Он считывает метаданные из ваших моделей и предоставляет быстрый интерфейс, ориентированный на модели, с помощью которого пользователи, которым вы доверяете, могут управлять содержимым сайта. Рекомендуется использовать админку только как внутренний инструмент управления организации. Она не предназначена для построения всего пользовательского интерфейса на её основе.
Админка предоставляет множество хуков для настройки, но будьте осторожны и не пытайтесь использовать исключительно эти хуки. Если вам нужен интерфейс, ориентированный на процессы и скрывающий детали реализации таблиц и полей базы данных, вероятно, пришло время написать собственные представления.
В этом документе рассказывается, как активировать, использовать и настраивать интерфейс администрирования Django.
Обзор
Админка включена в шаблон проекта по умолчанию, используемый командой startproject.
Если вы не используете шаблон проекта по умолчанию, необходимо выполнить следующие требования:
- Добавьте
'django.contrib.admin'и его зависимости —django.contrib.auth,django.contrib.contenttypes,django.contrib.messagesиdjango.contrib.sessions— в параметрINSTALLED_APPS. - Настройте бэкенд
DjangoTemplatesв параметреTEMPLATES, указавdjango.template.context_processors.request,django.contrib.auth.context_processors.authиdjango.contrib.messages.context_processors.messagesв параметре'context_processors'параметраOPTIONS. - Если вы настроили параметр
MIDDLEWARE, в него необходимо включитьdjango.contrib.sessions.middleware.SessionMiddleware,django.contrib.auth.middleware.AuthenticationMiddlewareиdjango.contrib.messages.middleware.MessageMiddleware. - Добавьте URL-адреса админки в конфигурацию URL.
После выполнения этих шагов вы сможете пользоваться сайтом администрирования, перейдя по URL-адресу, к которому вы его подключили (по умолчанию — /admin/).
Если вам нужно создать пользователя для входа, используйте команду createsuperuser. По умолчанию для входа в админку у пользователя должен быть установлен атрибут is_staff со значением True.
Наконец, определите, какие модели приложения должны быть доступны для редактирования в интерфейсе администрирования. Для каждой такой модели зарегистрируйте её в админке, как описано в разделе ModelAdmin.
Другие темы
- Действия админки
ModelAdminФильтры списков- Генератор документации админки Django
- Настройка JavaScript в админке
См. также
Информацию о раздаче статических файлов (изображений, JavaScript и CSS), связанных с админкой, в рабочей среде см. в разделе Раздача файлов.
Возникли проблемы? Ознакомьтесь с разделом Часто задаваемые вопросы: админка.
Объекты ModelAdmin
-
class ModelAdmin[исходный код] -
Класс
ModelAdminпредставляет модель в интерфейсе администрирования. Обычно такие классы хранятся в файле с именемadmin.pyв вашем приложении. Рассмотрим примерModelAdmin:from django.contrib import admin from myapp.models import Author class AuthorAdmin(admin.ModelAdmin): pass admin.site.register(Author, AuthorAdmin)Нужен ли вам вообще объект
ModelAdmin?В предыдущем примере класс
ModelAdminпока не определяет пользовательские значения. Поэтому будет предоставлен интерфейс администрирования по умолчанию. Если вас устраивает интерфейс администрирования по умолчанию, определять объектModelAdminне нужно — можно зарегистрировать класс модели, не предоставляя описаниеModelAdmin. Предыдущий пример можно упростить следующим образом:from django.contrib import admin from myapp.models import Author admin.site.register(Author)
Декоратор register
-
register(*models, site=django.contrib.admin.sites.site)[исходный код] -
Для регистрации классов
ModelAdminтакже предусмотрен декоратор:from django.contrib import admin from .models import Author @admin.register(Author) class AuthorAdmin(admin.ModelAdmin): passЕму передаются один или несколько классов моделей для регистрации в
ModelAdmin. Если вы используете пользовательскийAdminSite, передайте его с помощью именованного аргументаsite:from django.contrib import admin from .models import Author, Editor, Reader from myproject.admin_site import custom_admin_site @admin.register(Author, Reader, Editor, site=custom_admin_site) class PersonAdmin(admin.ModelAdmin): passЭтот декоратор нельзя использовать, если вам нужно ссылаться на класс администрирования модели в его методе
__init__(), напримерsuper(PersonAdmin, self).__init__(*args, **kwargs). В этом случае можно использоватьsuper().__init__(*args, **kwargs).
Обнаружение файлов админки
Когда вы добавляете 'django.contrib.admin' в параметр INSTALLED_APPS, Django автоматически ищет модуль admin в каждом приложении и импортирует его.
-
class apps.AdminConfig -
Это класс
AppConfigадминки по умолчанию. При запуске Django он вызываетautodiscover().
-
class apps.SimpleAdminConfig -
Этот класс работает так же, как
AdminConfig, за исключением того, что он не вызываетautodiscover().-
default_site -
Путь импорта через точку к классу сайта администрирования по умолчанию или к вызываемому объекту, который возвращает экземпляр сайта. По умолчанию —
'django.contrib.admin.sites.AdminSite'. Инструкции по использованию см. в разделе Переопределение сайта администрирования по умолчанию.
-
-
autodiscover()[исходный код] -
Эта функция пытается импортировать модуль
adminиз каждого установленного приложения. Предполагается, что такие модули регистрируют модели в админке.Обычно вызывать эту функцию напрямую не нужно, поскольку
AdminConfigвызывает её при запуске Django.
Если вы используете пользовательский AdminSite, часто бывает удобно импортировать в код все подклассы ModelAdmin и зарегистрировать их в пользовательском AdminSite. В этом случае, чтобы отключить автоматическое обнаружение, вместо 'django.contrib.admin' необходимо указать 'django.contrib.admin.apps.SimpleAdminConfig' в параметре INSTALLED_APPS.
ModelAdmin параметры
ModelAdmin очень гибок. Он имеет несколько параметров для настройки интерфейса. Все параметры определяются в подклассе ModelAdmin:
from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
date_hierarchy = "pub_date"
-
ModelAdmin.actions -
Список действий, доступных на странице списка изменений. Подробности см. в разделе Действия администратора.
-
ModelAdmin.actions_on_top
-
ModelAdmin.actions_on_bottom -
Определяет, где на странице отображается панель действий. По умолчанию список изменений в административном интерфейсе отображает действия в верхней части страницы (
actions_on_top = True; actions_on_bottom = False).
-
ModelAdmin.actions_selection_counter -
Определяет, отображается ли рядом с раскрывающимся списком действий счётчик выбранных элементов. По умолчанию список изменений в административном интерфейсе отображает этот счётчик (
actions_selection_counter = True).
-
ModelAdmin.date_hierarchy -
Задайте для
date_hierarchyимяDateFieldилиDateTimeFieldв модели, и на странице списка изменений появится навигация по датам для этого поля.Пример:
date_hierarchy = "pub_date"
Можно также указать поле связанной модели, используя поиск
__, например:date_hierarchy = "author__pub_date"
Навигация будет автоматически сформирована на основе доступных данных. Например, если все даты относятся к одному месяцу, будет отображаться только навигация с детализацией по дням.
Примечание
date_hierarchyвнутри используетQuerySet.datetimes(). Если поддержка часовых поясов включена (USE_TZ = True), ознакомьтесь с документацией этой функции, где описаны некоторые ограничения.
-
ModelAdmin.empty_value_display -
Этот атрибут переопределяет значение, отображаемое по умолчанию для пустых полей записи (
None, пустая строка и т. д.). Значение по умолчанию —-(тире). Например:from django.contrib import admin class AuthorAdmin(admin.ModelAdmin): empty_value_display = "-empty-"Можно также переопределить
empty_value_displayдля всех страниц административного интерфейса с помощьюAdminSite.empty_value_displayили для отдельных полей, как показано ниже:from django.contrib import admin class AuthorAdmin(admin.ModelAdmin): list_display = ["name", "title", "view_birth_date"] @admin.display(empty_value="???") def view_birth_date(self, obj): return obj.birth_date
-
ModelAdmin.exclude -
Если задан, этот атрибут должен содержать список имён полей, которые нужно исключить из формы.
Например, рассмотрим следующую модель:
from django.db import models class Author(models.Model): name = models.CharField(max_length=100) title = models.CharField(max_length=3) birth_date = models.DateField(blank=True, null=True)Если нужна форма для модели
Author, включающая только поляnameиtitle, укажитеfieldsилиexcludeследующим образом:from django.contrib import admin class AuthorAdmin(admin.ModelAdmin): fields = ["name", "title"] class AuthorAdmin(admin.ModelAdmin): exclude = ["birth_date"]Поскольку модель Author содержит только три поля —
name,titleиbirth_date, — в формах, созданных на основе приведённых выше объявлений, будут одни и те же поля.
-
ModelAdmin.fields -
Используйте параметр
fieldsдля простого изменения расположения полей в формах на страницах добавления и изменения: например, чтобы показывать только часть доступных полей, изменить их порядок или сгруппировать их в строки. Например, можно создать упрощённую версию административной формы для моделиdjango.contrib.flatpages.models.FlatPageследующим образом:class FlatPageAdmin(admin.ModelAdmin): fields = ["url", "title", "content"]В приведённом примере в форме последовательно отображаются только поля
url,titleиcontent.fieldsможет содержать значения, определённые вModelAdmin.readonly_fields, которые будут отображаться только для чтения.Для более сложного расположения полей см. параметр
fieldsets.Параметр
fieldsпринимает те же типы значений, что иlist_display, за исключением вызываемых объектов и поисков__для связанных полей. Имена методов модели и административного класса модели будут использоваться только в том случае, если они перечислены вreadonly_fields.Чтобы расположить несколько полей в одной строке, заключите их в отдельный кортеж. В этом примере поля
urlиtitleбудут расположены в одной строке, а полеcontent— в следующей строке:class FlatPageAdmin(admin.ModelAdmin): fields = [("url", "title"), "content"]Возможная путаница с параметром
ModelAdmin.fieldsetsНе следует путать этот параметр
fieldsс ключом словаряfields, который используется в параметреfieldsets, как описано в следующем разделе.Если не заданы ни параметр
fields, ни параметрfieldsets, Django по умолчанию отобразит в одном наборе полей все поля, которые не являютсяAutoFieldи имеютeditable=True, в том же порядке, в котором они определены в модели, а затем — все поля, заданные вreadonly_fields.
-
ModelAdmin.fieldsets -
Задайте
fieldsets, чтобы управлять расположением элементов на страницах добавления и изменения в административном интерфейсе.fieldsets— это список пар из двух элементов, каждая из которых представляет<fieldset>на странице административной формы. (<fieldset>— это «раздел» формы.)Пары имеют формат
(name, field_options), гдеname— строка, задающая заголовок набора полей, аfield_options— словарь с информацией о наборе полей, включая список отображаемых в нём полей.Полный пример из модели
django.contrib.flatpages.models.FlatPage:from django.contrib import admin class FlatPageAdmin(admin.ModelAdmin): fieldsets = [ ( None, { "fields": ["url", "title", "content", "sites"], }, ), ( "Advanced options", { "classes": ["collapse"], "fields": ["registration_required", "template_name"], }, ), ]В результате получится административная страница следующего вида:
Если не заданы ни параметр
fieldsets, ни параметрfields, Django по умолчанию отобразит в одном наборе полей все поля, которые не являютсяAutoFieldи имеютeditable=True, в том же порядке, в котором они определены в модели.Словарь
field_optionsможет содержать следующие ключи:-
-
fields -
Список или кортеж имён полей, которые нужно отобразить в этом наборе полей. Этот ключ обязателен.
Пример:
{ "fields": ["first_name", "last_name", "address", "city", "state"], }Как и в случае с параметром
fields, чтобы расположить несколько полей в одной строке, заключите их в отдельный кортеж. В этом примере поляfirst_nameиlast_nameбудут расположены в одной строке:{ "fields": [("first_name", "last_name"), "address", "city", "state"], }fieldsможет содержать значения, определённые вreadonly_fields, которые будут отображаться только для чтения.Если добавить имя вызываемого объекта в
fields, будет действовать то же правило, что и для параметраfields: вызываемый объект должен быть перечислен вreadonly_fields.
-
-
-
classes -
Список или кортеж дополнительных CSS-классов, применяемых к набору полей. Можно указать любые пользовательские CSS-классы, определённые в проекте, а также CSS-классы, предоставляемые Django. В таблице стилей CSS по умолчанию для административного интерфейса определены два особенно полезных класса:
collapseиwide.Пример:
{ "classes": ["wide", "collapse"], }Наборам полей со стилем
wideбудет предоставлено дополнительное горизонтальное пространство в административном интерфейсе. Наборы полей с именем и стилемcollapseизначально будут свёрнуты; их видимость можно переключать с помощью раскрывающегося элемента управления.
-
-
-
description -
Необязательная строка дополнительного текста, отображаемого в верхней части каждого набора полей под его заголовком.
Обратите внимание, что при отображении в административном интерфейсе это значение не экранируется как HTML. Это позволяет при необходимости включать HTML. Также можно использовать обычный текст и функцию
django.utils.html.escape(), чтобы экранировать специальные символы HTML.
-
TabularInlineподдерживаетfieldsetsлишь частичноФункциональность
fieldsetsпри использовании сTabularInlineограничена. Можно указать отображаемые поля и их порядок в макетеTabularInline, задавfieldsв словареfield_options.Остальные функции не поддерживаются. В частности, нельзя использовать
nameдля задания заголовка группы полей. -
-
ModelAdmin.filter_horizontal -
По умолчанию поле
ManyToManyFieldотображается на сайте администрирования в виде<select multiple>. Однако окна множественного выбора могут быть неудобны, когда нужно выбрать много элементов. Если добавить в этот список полеManyToManyField, вместо него будет использоваться удобный ненавязчивый JavaScript-интерфейс «фильтра», позволяющий искать среди вариантов. Не выбранные и выбранные варианты отображаются в двух расположенных рядом окнах. Чтобы использовать вертикальный интерфейс, см.filter_vertical.
-
ModelAdmin.filter_vertical -
Аналогичен
filter_horizontal, но интерфейс фильтра отображается вертикально: окно с невыбранными вариантами находится над окном с выбранными.
-
ModelAdmin.form -
По умолчанию для вашей модели динамически создаётся
ModelForm. Она используется для создания формы, отображаемой на страницах добавления и изменения. Вы можете легко предоставить собственныйModelForm, чтобы переопределить поведение формы по умолчанию на этих страницах. Также можно настроить форму по умолчанию, не создавая новую целиком, с помощью методаModelAdmin.get_form().Пример приведён в разделе Добавление пользовательской проверки в административный интерфейс.
Приоритет имеет
ModelAdmin.excludeЕсли в вашем
ModelFormиModelAdminзадан один и тот же параметрexclude, приоритет имеетModelAdmin:from django import forms from django.contrib import admin from myapp.models import Person class PersonForm(forms.ModelForm): class Meta: model = Person exclude = ["name"] class PersonAdmin(admin.ModelAdmin): exclude = ["age"] form = PersonFormВ приведённом примере поле «age» будет исключено, а поле «name» включено в созданную форму.
-
ModelAdmin.formfield_overrides -
Этот параметр позволяет быстро и без лишних сложностей переопределить некоторые параметры
Fieldдля административного интерфейса.formfield_overrides— это словарь, сопоставляющий класс поля со словарём аргументов, передаваемых полю при создании.Поскольку это описание довольно абстрактно, рассмотрим конкретный пример. Чаще всего
formfield_overridesиспользуется для добавления пользовательского виджета для определённого типа поля. Представим, что мы написалиRichTextEditorWidget, который хотим использовать для больших текстовых полей вместо стандартного<textarea>. Вот как это сделать:from django.contrib import admin from django.db import models # Import our custom widget and our model from where they're defined from myapp.models import MyModel from myapp.widgets import RichTextEditorWidget class MyModelAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: {"widget": RichTextEditorWidget}, }Обратите внимание: ключом словаря является сам класс поля, а не строка. Значение — другой словарь; эти аргументы будут переданы методу
__init__()поля формы. Подробности см. в разделе API форм.Предупреждение
Если вы хотите использовать пользовательский виджет для поля связи (например,
ForeignKeyилиManyToManyField), убедитесь, что имя этого поля не включено вraw_id_fields,radio_fieldsилиautocomplete_fields.formfield_overridesне позволяет менять виджет полей связи, для которых заданыraw_id_fields,radio_fieldsилиautocomplete_fields. Это связано с тем, чтоraw_id_fields,radio_fieldsиautocomplete_fieldsподразумевают использование собственных пользовательских виджетов.
-
ModelAdmin.inlines -
См. также приведённые ниже объекты
InlineModelAdminиModelAdmin.get_formsets_with_inlines().
-
ModelAdmin.list_display -
Задайте
list_display, чтобы управлять полями, отображаемыми на странице списка изменений в административном интерфейсе.Пример:
list_display = ["first_name", "last_name"]
Если не задавать
list_display, сайт администрирования будет отображать один столбец с представлением каждого объекта, полученным с помощью__str__().В
list_displayможно использовать пять типов значений. Для всех, кроме самого простого типа, можно использовать декораторdisplay(), позволяющий настраивать отображение поля:-
Имя поля модели. Например:
class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "last_name"] -
Имя связанного поля с использованием нотации
__. Например:class PersonAdmin(admin.ModelAdmin): list_display = ["city__name"] -
Вызываемый объект, принимающий один аргумент — экземпляр модели. Например:
@admin.display(description="Name") def upper_case_name(obj): return f"{obj.first_name} {obj.last_name}".upper() class PersonAdmin(admin.ModelAdmin): list_display = [upper_case_name] -
Строка, представляющая метод
ModelAdmin, который принимает один аргумент — экземпляр модели. Например:class PersonAdmin(admin.ModelAdmin): list_display = ["upper_case_name"] @admin.display(description="Name") def upper_case_name(self, obj): return f"{obj.first_name} {obj.last_name}".upper() -
Строка, представляющая атрибут или метод модели (без обязательных аргументов). Например:
from django.contrib import admin from django.db import models class Person(models.Model): name = models.CharField(max_length=50) birthday = models.DateField() @admin.display(description="Birth decade") def decade_born_in(self): decade = self.birthday.year // 10 * 10 return f"{decade}’s" class PersonAdmin(admin.ModelAdmin): list_display = ["name", "decade_born_in"]
Обратите внимание на несколько особенностей
list_display:- Если поле является
ForeignKey, Django отобразит__str__()связанного объекта. -
Поля
ManyToManyFieldне поддерживаются, поскольку для этого пришлось бы выполнять отдельный SQL-запрос для каждой строки таблицы. Если вы всё же хотите это сделать, добавьте в модель пользовательский метод и включите его имя вlist_display. (Подробнее о пользовательских методах вlist_displayсм. ниже.) - Если поле является
BooleanField, Django отобразит вместоTrue,FalseилиNoneсоответствующий значок: «да», «нет» или «неизвестно». -
Если указанная строка представляет метод модели,
ModelAdminили вызываемый объект, Django по умолчанию экранирует HTML в результате. Чтобы экранировать пользовательский ввод и использовать собственные неэкранированные теги, применяйтеformat_html().Вот полный пример модели:
from django.contrib import admin from django.db import models from django.utils.html import format_html class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) @admin.display def colored_name(self): return format_html( '<span style="color: #{};">{} {}</span>', self.color_code, self.first_name, self.last_name, ) class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "last_name", "colored_name"] - Как уже показывают некоторые примеры, при использовании вызываемого объекта, метода модели или метода
ModelAdminможно настроить заголовок столбца: оберните вызываемый объект декораторомdisplay()и передайте аргументdescription. -
Если значение поля равно
None, является пустой строкой или представляет собой пустой итерируемый объект, Django отобразит-(тире). Это можно переопределить с помощьюAdminSite.empty_value_display:from django.contrib import admin admin.site.empty_value_display = "(None)"
Можно также использовать
ModelAdmin.empty_value_display:class PersonAdmin(admin.ModelAdmin): empty_value_display = "unknown"Или задать значение для отдельного поля:
class PersonAdmin(admin.ModelAdmin): list_display = ["name", "birth_date_view"] @admin.display(empty_value="unknown") def birth_date_view(self, obj): return obj.birth_date -
Если указанная строка представляет метод модели,
ModelAdminили вызываемый объект, возвращающийTrue,FalseилиNone, Django отобразит соответствующий значок: «да», «нет» или «неизвестно», если обернуть метод декораторомdisplay(), передав аргументbooleanсо значениемTrue:from django.contrib import admin from django.db import models class Person(models.Model): first_name = models.CharField(max_length=50) birthday = models.DateField() @admin.display(boolean=True) def born_in_fifties(self): return 1950 <= self.birthday.year < 1960 class PersonAdmin(admin.ModelAdmin): list_display = ["name", "born_in_fifties"] -
Метод
__str__()вlist_displayничем не отличается от любого другого метода модели, поэтому вполне допустимо поступить так:list_display = ["__str__", "some_other_field"]
-
Как правило, элементы
list_display, которые не являются реальными полями базы данных, нельзя использовать для сортировки (поскольку Django выполняет сортировку на уровне базы данных).Однако если элемент
list_displayпредставляет определённое поле базы данных, это можно указать с помощью декоратораdisplay(), передав аргументordering:from django.contrib import admin from django.db import models from django.utils.html import format_html class Person(models.Model): first_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) @admin.display(ordering="first_name") def colored_first_name(self): return format_html( '<span style="color: #{};">{}</span>', self.color_code, self.first_name, ) class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "colored_first_name"]В приведённом примере Django будет сортировать по полю
first_nameпри попытке отсортировать список поcolored_first_nameв административном интерфейсе.Чтобы указать сортировку по убыванию с помощью аргумента
ordering, добавьте дефис перед именем поля. В приведённом примере это будет выглядеть так:@admin.display(ordering="-first_name") def colored_first_name(self): ...
Аргумент
orderingподдерживает поиски по запросу для сортировки по значениям связанных моделей. В этом примере в отображение списка добавляется столбец «имя автора», который можно сортировать по имени:class Blog(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey(Person, on_delete=models.CASCADE) class BlogAdmin(admin.ModelAdmin): list_display = ["title", "author", "author_first_name"] @admin.display(ordering="author__first_name") def author_first_name(self, obj): return obj.author.first_nameС аргументом
orderingможно использовать выражения запросов:from django.db.models import Value from django.db.models.functions import Concat class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @admin.display(ordering=Concat("first_name", Value(" "), "last_name")) def full_name(self): return self.first_name + " " + self.last_name -
Элементы
list_displayтакже могут быть свойствамиclass Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @property @admin.display( ordering="last_name", description="Full name of the person", boolean=False, ) def full_name(self): return self.first_name + " " + self.last_name class PersonAdmin(admin.ModelAdmin): list_display = ["full_name"]Обратите внимание, что
@propertyдолжен располагаться выше@display. Если вы используете старый способ — задаёте атрибуты отображения напрямую, а не с помощью декоратораdisplay(), — учтите, что нужно использовать функциюproperty(), а не декоратор@property:def my_property(self): return self.first_name + " " + self.last_name my_property.short_description = "Full name of the person" my_property.admin_order_field = "last_name" my_property.boolean = False full_name = property(my_property) - Имена полей в
list_displayтакже появятся в HTML-выводе в виде CSS-классов:column-<field_name>для каждого элемента<th>. Например, это можно использовать для задания ширины столбцов в CSS-файле. -
Django будет интерпретировать каждый элемент
list_displayв следующем порядке:- Поле модели или связанное поле.
- Вызываемый объект.
- Строка, представляющая атрибут
ModelAdmin. - Строка, представляющая атрибут модели.
Например, если
first_nameявляется и полем модели, и атрибутомModelAdmin, будет использовано поле модели.
-
-
ModelAdmin.list_display_links -
Используйте
list_display_links, чтобы указать, какие поля изlist_displayдолжны ссылаться на страницу изменения объекта.По умолчанию на странице списка изменений первая колонка — первое поле, указанное в
list_display, — ссылается на страницу изменения соответствующего элемента. Параметрlist_display_linksпозволяет изменить это поведение:- Задайте значение
None, чтобы отключить все ссылки. -
Задайте список или кортеж полей (в том же формате, что и
list_display), столбцы которых нужно превратить в ссылки.Можно указать одно или несколько полей. Если поля присутствуют в
list_display, Django не ограничивает количество полей, на которые можно добавить ссылки. Единственное требование: чтобы использоватьlist_display_linksтаким образом, необходимо определитьlist_display.
В этом примере на странице списка изменений поля
first_nameиlast_nameбудут ссылками:class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "last_name", "birthday"] list_display_links = ["first_name", "last_name"]В этом примере в таблице на странице списка изменений не будет ссылок:
class AuditEntryAdmin(admin.ModelAdmin): list_display = ["timestamp", "message"] list_display_links = None - Задайте значение
-
ModelAdmin.list_editable -
Задайте для
list_editableсписок имён полей модели, которые можно редактировать на странице списка изменений. Поля, перечисленные вlist_editable, будут отображаться на странице списка изменений в виде полей формы, позволяя пользователям редактировать и сохранять сразу несколько строк.Примечание
list_editableопределённым образом взаимодействует с несколькими другими параметрами. Обратите внимание на следующие правила:- Любое поле из
list_editableдолжно также присутствовать вlist_display. Нельзя редактировать поле, которое не отображается! - Одно и то же поле нельзя указывать одновременно в
list_editableиlist_display_links: поле не может быть одновременно элементом формы и ссылкой.
При нарушении любого из этих правил возникнет ошибка проверки.
- Любое поле из
-
ModelAdmin.list_filter -
Задайте
list_filter, чтобы включить фильтры в правой боковой панели страницы списка изменений административного интерфейса.В простейшем случае
list_filterпринимает список или кортеж имён полей, по которым нужно включить фильтрацию, но доступны и более сложные варианты. Подробности см. в разделе Фильтры списков ModelAdmin.
-
ModelAdmin.list_max_show_all -
Задайте
list_max_show_all, чтобы определить максимальное число элементов на странице списка изменений административного интерфейса с включённым режимом «Показать все». Ссылка «Показать все» появится на странице списка изменений, только если общее число результатов не превышает это значение. По умолчанию оно равно200.
-
ModelAdmin.list_per_page -
Задайте
list_per_page, чтобы определить число элементов на каждой странице списка изменений административного интерфейса с постраничной навигацией. По умолчанию оно равно100.
-
Установите
list_select_related, чтобы указать Django использоватьselect_related()при получении списка объектов на странице списка изменений в админке. Это поможет сократить количество запросов к базе данных.Значением должен быть логический тип, список или кортеж. По умолчанию используется
False.Если значение —
True,select_related()будет вызываться всегда. Если задано значениеFalse, Django проверитlist_displayи вызоветselect_related(), если присутствует хотя бы одинForeignKey.Если вам нужен более точный контроль, используйте кортеж (или список) в качестве значения
list_select_related. Пустой кортеж не позволит Django вызыватьselect_related. Любой другой кортеж будет напрямую передан вselect_relatedв качестве параметров. Например:class ArticleAdmin(admin.ModelAdmin): list_select_related = ["author", "category"]вызовет
select_related('author', 'category').Если нужно задать динамическое значение на основе запроса, можно реализовать метод
get_list_select_related().Примечание
ModelAdminигнорирует этот атрибут, еслиselect_related()уже был вызван дляQuerySetсписка изменений.
-
ModelAdmin.ordering -
Установите
ordering, чтобы указать порядок сортировки списков объектов в представлениях админки Django. Значением должен быть список или кортеж в том же формате, что и параметрorderingмодели.Если это значение не задано, админка Django будет использовать порядок сортировки модели по умолчанию.
Если нужно задать динамический порядок сортировки (например, в зависимости от пользователя или языка), можно реализовать метод
get_ordering().Вопросы производительности при упорядочивании и сортировке
Чтобы обеспечить детерминированный порядок результатов, список изменений добавляет
pkк порядку сортировки, если не находит единственное или уникальное сочетание полей, задающее полный порядок.Например, если порядок сортировки по умолчанию задан по неуникальному полю
name, список изменений сортируется поnameиpk. Это может работать медленно при большом количестве строк, если дляnameиpkне создан индекс.
-
ModelAdmin.paginator -
Класс пагинатора, используемый для разбиения на страницы. По умолчанию используется
django.core.paginator.Paginator. Если пользовательский класс пагинатора не имеет такого же интерфейса конструктора, какdjango.core.paginator.Paginator, необходимо также предоставить реализациюModelAdmin.get_paginator().
-
ModelAdmin.prepopulated_fields -
Задайте
prepopulated_fieldsкак словарь, сопоставляющий имена полей с полями, значения которых будут использоваться для их предварительного заполнения:class ArticleAdmin(admin.ModelAdmin): prepopulated_fields = {"slug": ["title"]}При задании этого параметра указанные поля будут заполняться с помощью JavaScript на основе назначенных полей. Чаще всего эта возможность используется для автоматической генерации значений полей
SlugFieldна основе одного или нескольких других полей. Значение генерируется путем объединения значений исходных полей с последующим преобразованием результата в допустимый слаг (например, пробелы заменяются дефисами, а буквы ASCII переводятся в нижний регистр).После сохранения значения JavaScript больше не изменяет предварительно заполненные поля. Обычно нежелательно, чтобы слаги менялись (если слаг входит в URL объекта, это приведет к изменению URL).
prepopulated_fieldsне принимает поляDateTimeField,ForeignKey,OneToOneFieldиManyToManyField.
-
ModelAdmin.preserve_filters -
По умолчанию примененные фильтры сохраняются в представлении списка после создания, редактирования или удаления объекта. Чтобы сбрасывать фильтры, установите для этого атрибута значение
False.
-
ModelAdmin.show_facets -
Определяет, отображаются ли счетчики фасетов для фильтров в списке изменений админки. По умолчанию используется
ShowFacets.ALLOW.При отображении счетчики фасетов обновляются с учетом текущих фильтров.
-
class ShowFacets -
Перечисление допустимых значений для
ModelAdmin.show_facets.-
ALWAYS -
Всегда отображать счетчики фасетов.
-
ALLOW -
Отображать счетчики фасетов, если указан параметр строки запроса
_facets.
-
NEVER -
Никогда не отображать счетчики фасетов.
-
Задайте для
show_facetsнужное значениеShowFacets. Например, чтобы всегда отображать счетчики фасетов без указания параметра запроса:from django.contrib import admin class MyModelAdmin(admin.ModelAdmin): ... # Have facets always shown for this model admin. show_facets = admin.ShowFacets.ALWAYSВопросы производительности при использовании фасетов
Включение фильтров с фасетами увеличит количество запросов на странице списка изменений админки пропорционально числу фильтров. Эти запросы могут привести к проблемам с производительностью, особенно при работе с большими наборами данных. В таких случаях может быть целесообразно задать для
show_facetsзначениеShowFacets.NEVER, чтобы полностью отключить фасеты. -
-
ModelAdmin.radio_fields -
По умолчанию админка Django использует для полей интерфейс с раскрывающимся списком (<select>), если они имеют тип
ForeignKeyили для них заданоchoices. Если поле указано вradio_fields, Django вместо этого использует интерфейс с переключателями. Предположим, чтоgroup— этоForeignKeyмоделиPerson:class PersonAdmin(admin.ModelAdmin): radio_fields = {"group": admin.VERTICAL}Можно выбрать
HORIZONTALилиVERTICALиз модуляdjango.contrib.admin.Не добавляйте поле в
radio_fields, если оно не имеет типForeignKeyи для него не заданоchoices.
-
ModelAdmin.autocomplete_fields -
autocomplete_fields— это список полейForeignKeyи/илиManyToManyField, для которых нужно использовать поля автозаполнения Select2.По умолчанию для этих полей админка использует интерфейс с раскрывающимся списком (
<select>). Иногда нежелательно нести накладные расходы, связанные с выборкой всех связанных экземпляров для отображения в списке.Поле Select2 выглядит похоже на стандартное поле ввода, но имеет функцию поиска, которая асинхронно загружает варианты. Это быстрее и удобнее для пользователя, если у связанной модели много экземпляров.
В
ModelAdminсвязанного объекта необходимо определитьsearch_fields, поскольку оно используется для поиска в поле автозаполнения.Чтобы предотвратить раскрытие данных неавторизованным пользователям, для использования автозаполнения им необходимо иметь разрешение
viewилиchangeна связанный объект.Сортировка и разбиение результатов на страницы управляются методами
get_ordering()иget_paginator()связанногоModelAdmin.В следующем примере у
ChoiceAdminесть поле автозаполнения дляForeignKey, связанного сQuestion. Результаты фильтруются по полюquestion_textи сортируются по полюdate_created:class QuestionAdmin(admin.ModelAdmin): ordering = ["date_created"] search_fields = ["question_text"] class ChoiceAdmin(admin.ModelAdmin): autocomplete_fields = ["question"]Вопросы производительности при работе с большими наборами данных
Сортировка с помощью
ModelAdmin.orderingможет привести к проблемам с производительностью, поскольку сортировка большого набора запросов будет выполняться медленно.Кроме того, если среди полей поиска есть поля, для которых база данных не создала индексы, на очень больших таблицах производительность может оказаться низкой.
В таких случаях рекомендуется реализовать собственный метод
ModelAdmin.get_search_results(), использующий полнотекстовый поиск по индексированным данным.Для очень больших таблиц также может понадобиться изменить
Paginator, поскольку пагинатор по умолчанию всегда выполняет запросcount(). Например, можно переопределить реализацию свойстваPaginator.countпо умолчанию.
-
ModelAdmin.raw_id_fields -
По умолчанию админка Django использует для полей
ForeignKeyинтерфейс с раскрывающимся списком (<select>). Иногда нежелательно нести накладные расходы, связанные с выборкой всех связанных экземпляров для отображения в раскрывающемся списке.raw_id_fields— это список полей, для которых вместо этого нужно использовать виджетInputв случаеForeignKeyилиManyToManyField:class ArticleAdmin(admin.ModelAdmin): raw_id_fields = ["newspaper"]В виджете
raw_id_fieldsInputдолжен содержаться первичный ключ, если поле имеет типForeignKey, или список значений, разделенных запятыми, если поле имеет типManyToManyField. Виджетraw_id_fieldsотображает рядом с полем кнопку с лупой, позволяющую пользователям найти и выбрать значение:
-
ModelAdmin.readonly_fields -
По умолчанию админка отображает все поля доступными для редактирования. Данные всех полей, указанных в этом параметре (значением должен быть
listилиtuple), будут отображаться как есть и без возможности редактирования; кроме того, эти поля исключаются изModelForm, используемой для создания и редактирования. Обратите внимание: при указанииModelAdmin.fieldsилиModelAdmin.fieldsetsполя только для чтения необходимо включить в список, чтобы они отображались (в противном случае они игнорируются).Если
readonly_fieldsиспользуется без явного указания порядка с помощьюModelAdmin.fieldsилиModelAdmin.fieldsets, такие поля будут добавлены в конец, после всех редактируемых полей.Поле только для чтения может отображать не только данные поля модели, но и результат выполнения метода модели или метода самого класса
ModelAdmin. Это работает очень похоже наModelAdmin.list_display. Так можно использовать интерфейс админки для отображения состояния редактируемых объектов, например:from django.contrib import admin from django.utils.html import format_html_join from django.utils.safestring import mark_safe class PersonAdmin(admin.ModelAdmin): readonly_fields = ["address_report"] # description functions like a model field's verbose_name @admin.display(description="Address") def address_report(self, instance): # assuming get_full_address() returns a list of strings # for each line of the address and you want to separate each # line by a linebreak return format_html_join( mark_safe("<br>"), "{}", ((line,) for line in instance.get_full_address()), ) or mark_safe("<span class='errors'>I can't determine this address.</span>")
-
ModelAdmin.save_as -
Установите
save_as, чтобы включить функцию «сохранить как новый» в формах редактирования админки.Обычно для объектов доступны три варианта сохранения: «Сохранить», «Сохранить и продолжить редактирование» и «Сохранить и добавить другой». Если
save_asимеет значениеTrue, кнопка «Сохранить и добавить другой» будет заменена кнопкой «Сохранить как новый», которая создаст новый объект (с новым идентификатором), а не обновит существующий.По умолчанию
save_asимеет значениеFalse.
-
ModelAdmin.save_as_continue -
При включенном параметре
save_as=Trueпосле сохранения нового объекта по умолчанию выполняется перенаправление на страницу редактирования этого объекта. Если задатьsave_as_continue=False, перенаправление будет вести на страницу списка изменений.По умолчанию
save_as_continueимеет значениеTrue.
-
ModelAdmin.save_on_top -
Установите
save_on_top, чтобы добавить кнопки сохранения в верхнюю часть форм редактирования админки.Обычно кнопки сохранения отображаются только в нижней части форм. Если задать
save_on_top, кнопки будут отображаться и вверху, и внизу.По умолчанию
save_on_topимеет значениеFalse.
-
ModelAdmin.search_fields -
Установите
search_fields, чтобы включить поле поиска на странице списка изменений админки. В качестве значения следует указать список имен полей, по которым будет выполняться поиск при отправке запроса из этого текстового поля.Это должны быть поля текстового типа, например
CharFieldилиTextField. Также можно выполнять поиск по связанным объектам типаForeignKeyилиManyToManyField, используя нотацию «перехода» API поиска:search_fields = ["foreign_key__related_fieldname"]
Например, если у записи блога есть автор, следующее определение позволит искать записи блога по адресу электронной почты автора:
search_fields = ["user__email"]
Когда пользователь выполняет поиск в поле поиска админки, Django разбивает запрос на слова и возвращает все объекты, содержащие каждое из этих слов без учета регистра (используя поиск
icontains), причем каждое слово должно присутствовать хотя бы в одном из полейsearch_fields. Например, еслиsearch_fieldsзадано как['first_name', 'last_name']и пользователь ищетjohn lennon, Django выполнит SQL-условиеWHERE, эквивалентное следующему:WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%') AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
Поисковый запрос может содержать фразы в кавычках с пробелами. Например, если пользователь ищет
"john winston"или'john winston', Django выполнит SQL-условиеWHERE, эквивалентное следующему:WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')
Если вы не хотите использовать
icontainsв качестве условия поиска, можно использовать любое условие, добавив его к имени поля. Например, можно использоватьexact, задавsearch_fieldsкак['first_name__exact'].Также доступны некоторые (устаревшие) сокращения для задания условия поиска. Можно добавить к полю в
search_fieldsодин из следующих символов, что эквивалентно добавлению к полю__<lookup>:Префикс
Условие поиска
^
=
@
None
Чтобы настроить поиск, используйте
ModelAdmin.get_search_results()для реализации дополнительного или альтернативного поведения поиска.
-
ModelAdmin.search_help_text -
Установите
search_help_text, чтобы задать поясняющий текст для поля поиска, который будет отображаться под ним.
-
ModelAdmin.show_full_result_count -
Установите
show_full_result_count, чтобы определить, следует ли отображать полное количество объектов на отфильтрованной странице админки (например,99 results (103 total)). Если для этого параметра задано значениеFalse, вместо этого отображается текст вроде99 results (Show all).Значение
show_full_result_count=Trueпо умолчанию приводит к выполнению запроса для подсчета всех записей в таблице, что может быть затратным, если таблица содержит большое количество строк.
-
ModelAdmin.sortable_by -
По умолчанию на странице списка изменений разрешена сортировка по всем полям модели (а также вызываемым объектам, для которых в декораторе
display()указан аргументorderingили задан атрибутadmin_order_field), перечисленным вlist_display.Чтобы отключить сортировку для некоторых столбцов, задайте для
sortable_byнабор (например,list,tupleилиset), содержащий подмножество элементовlist_display, которые должны поддерживать сортировку. Пустой набор отключает сортировку для всех столбцов.Если этот список нужно задавать динамически, реализуйте вместо этого метод
get_sortable_by().
-
ModelAdmin.view_on_site -
Установите
view_on_site, чтобы определить, отображать ли ссылку «Посмотреть на сайте». Эта ссылка должна вести на URL, по которому можно просмотреть сохраненный объект.Значением может быть логический флаг или вызываемый объект. Если задано
True(значение по умолчанию), URL создается с помощью методаget_absolute_url()объекта.Если у модели есть метод
get_absolute_url(), но вы не хотите отображать кнопку «Посмотреть на сайте», достаточно задать дляview_on_siteзначениеFalse:from django.contrib import admin class PersonAdmin(admin.ModelAdmin): view_on_site = FalseЕсли это вызываемый объект, он принимает экземпляр модели в качестве параметра. Например:
from django.contrib import admin from django.urls import reverse class PersonAdmin(admin.ModelAdmin): def view_on_site(self, obj): url = reverse("person-detail", kwargs={"slug": obj.slug}) return "https://example.com" + url
Параметры пользовательских шаблонов
В разделе Переопределение шаблонов админки описано, как переопределить или расширить шаблоны админки по умолчанию. Используйте следующие параметры, чтобы переопределить шаблоны по умолчанию, применяемые представлениями ModelAdmin:
-
ModelAdmin.add_form_template -
Путь к пользовательскому шаблону, используемому в
add_view().
-
ModelAdmin.change_form_template -
Путь к пользовательскому шаблону, используемому в
change_view().
-
ModelAdmin.change_list_template -
Путь к пользовательскому шаблону, используемому в
changelist_view().
-
ModelAdmin.delete_confirmation_template -
Путь к пользовательскому шаблону, используемому в
delete_view()для отображения страницы подтверждения при удалении одного или нескольких объектов.
-
ModelAdmin.delete_selected_confirmation_template -
Путь к пользовательскому шаблону, используемому методом действия
delete_selectedдля отображения страницы подтверждения при удалении одного или нескольких объектов. См. документацию по действиям.
-
ModelAdmin.object_history_template -
Путь к пользовательскому шаблону, используемому в
history_view().
-
ModelAdmin.popup_response_template -
Путь к пользовательскому шаблону, используемому в
response_add(),response_change()иresponse_delete().
ModelAdmin методы
Предупреждение
При переопределении ModelAdmin.save_model() и ModelAdmin.delete_model() ваш код должен сохранять или удалять объект. Эти методы предназначены не для запрета действий, а для выполнения дополнительных операций.
-
ModelAdmin.save_model(request, obj, form, change)[источник] -
Метод
save_modelполучаетHttpRequest, экземпляр модели, экземплярModelFormи логическое значение, определяющее, добавляется или изменяется объект. Переопределение этого метода позволяет выполнять операции до или после сохранения. Вызовитеsuper().save_model(), чтобы сохранить объект с помощьюModel.save().Например, чтобы добавить
request.userк объекту перед сохранением:from django.contrib import admin class ArticleAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): obj.user = request.user super().save_model(request, obj, form, change)
-
ModelAdmin.delete_model(request, obj)[источник] -
Метод
delete_modelполучаетHttpRequestи экземпляр модели. Переопределение этого метода позволяет выполнять операции до или после удаления. Вызовитеsuper().delete_model(), чтобы удалить объект с помощьюModel.delete().
-
ModelAdmin.delete_queryset(request, queryset)[источник] -
Метод
delete_queryset()получаетHttpRequestиQuerySetобъектов, подлежащих удалению. Переопределите этот метод, чтобы настроить процесс удаления для действия «удалить выбранные объекты».
-
ModelAdmin.save_formset(request, form, formset, change)[источник] -
Метод
save_formsetполучаетHttpRequest, родительский экземплярModelFormи логическое значение, определяющее, добавляется или изменяется родительский объект.Например, чтобы добавить
request.userк каждому изменённому экземпляру модели в наборе форм:class ArticleAdmin(admin.ModelAdmin): def save_formset(self, request, form, formset, change): instances = formset.save(commit=False) for obj in formset.deleted_objects: obj.delete() for instance in instances: instance.user = request.user instance.save() formset.save_m2m()См. также Сохранение объектов в наборе форм.
Предупреждение
Все хуки, возвращающие свойство ModelAdmin, возвращают само свойство, а не копию его значения. Динамическое изменение значения может привести к неожиданным результатам.
Рассмотрим в качестве примера ModelAdmin.get_readonly_fields():
class PersonAdmin(admin.ModelAdmin):
readonly_fields = ["name"]
def get_readonly_fields(self, request, obj=None):
readonly = super().get_readonly_fields(request, obj)
if not request.user.is_superuser:
readonly.append("age") # Edits the class attribute.
return readonly
В результате readonly_fields становится ["name", "age", "age",
...] даже для суперпользователя, поскольку "age" добавляется каждый раз, когда страницу посещает пользователь, не являющийся суперпользователем.
-
ModelAdmin.get_ordering(request) -
Метод
get_orderingпринимаетrequestв качестве параметра и должен возвращатьlistилиtupleдля сортировки, аналогично атрибутуordering. Например:class PersonAdmin(admin.ModelAdmin): def get_ordering(self, request): if request.user.is_superuser: return ["name", "rank"] else: return ["name"]
-
ModelAdmin.get_search_results(request, queryset, search_term)[источник] -
Метод
get_search_resultsизменяет список отображаемых объектов, оставляя в нём только те, которые соответствуют заданному поисковому запросу. Он принимает запрос, queryset с применёнными текущими фильтрами и поисковый запрос, введённый пользователем. Метод возвращает кортеж, содержащий queryset, изменённый для выполнения поиска, и логическое значение, указывающее, могут ли результаты содержать дубликаты.Реализация по умолчанию выполняет поиск по полям, указанным в
ModelAdmin.search_fields.Этот метод можно переопределить собственной реализацией поиска. Например, может потребоваться выполнять поиск по целочисленному полю или использовать внешний инструмент, например Solr или Haystack. Необходимо определить, могут ли изменения queryset, внесённые вашим методом поиска, приводить к появлению дубликатов в результатах, и вернуть
Trueво втором элементе возвращаемого значения.Например, для поиска по
nameиageможно использовать:class PersonAdmin(admin.ModelAdmin): list_display = ["name", "age"] search_fields = ["name"] def get_search_results(self, request, queryset, search_term): queryset, may_have_duplicates = super().get_search_results( request, queryset, search_term, ) try: search_term_as_int = int(search_term) except ValueError: pass else: queryset |= self.model.objects.filter(age=search_term_as_int) return queryset, may_have_duplicatesЭта реализация эффективнее, чем
search_fields = ('name', '=age'), которая приводит к сравнению строк для числового поля, например... OR UPPER("polls_choice"."votes"::text) = UPPER('4')в PostgreSQL.
-
Метод
save_relatedполучаетHttpRequest, родительский экземплярModelForm, список встроенных наборов форм и логическое значение, определяющее, добавляется или изменяется родительский объект. Здесь можно выполнять любые операции до или после сохранения объектов, связанных с родительским объектом. Обратите внимание: к этому моменту родительский объект и его форма уже сохранены.
-
ModelAdmin.get_autocomplete_fields(request) -
Метод
get_autocomplete_fields()получаетHttpRequestи должен возвращатьlistилиtupleимён полей, которые будут отображаться с виджетом автодополнения, описанным выше в разделеModelAdmin.autocomplete_fields.
-
ModelAdmin.get_readonly_fields(request, obj=None) -
Метод
get_readonly_fieldsполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращатьlistилиtupleимён полей, которые будут отображаться только для чтения, как описано выше в разделеModelAdmin.readonly_fields.
-
ModelAdmin.get_prepopulated_fields(request, obj=None) -
Метод
get_prepopulated_fieldsполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращатьdictionary, как описано выше в разделеModelAdmin.prepopulated_fields.
-
ModelAdmin.get_list_display(request)[источник] -
Метод
get_list_displayполучаетHttpRequestи должен возвращатьlistилиtupleимён полей, которые будут отображаться на странице списка изменений, как описано выше в разделеModelAdmin.list_display.
-
ModelAdmin.get_list_display_links(request, list_display)[источник] -
Метод
get_list_display_linksполучаетHttpRequestиlistилиtuple, возвращённый методомModelAdmin.get_list_display(). Он должен возвращать либоNone, либоlistилиtupleимён полей на странице списка изменений, которые будут ссылаться на страницу изменения объекта, как описано в разделеModelAdmin.list_display_links.
-
ModelAdmin.get_exclude(request, obj=None) -
Метод
get_excludeполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращать список полей, как описано вModelAdmin.exclude.
-
ModelAdmin.get_fields(request, obj=None) -
Метод
get_fieldsполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращать список полей, как описано выше в разделеModelAdmin.fields.
-
ModelAdmin.get_fieldsets(request, obj=None) -
Метод
get_fieldsetsполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращать список 2-кортежей, каждый из которых представляет<fieldset>на странице формы администратора, как описано выше в разделеModelAdmin.fieldsets.
-
ModelAdmin.get_list_filter(request)[источник] -
Метод
get_list_filterполучаетHttpRequestи должен возвращать последовательность того же типа, что и для атрибутаlist_filter.
-
Метод
get_list_select_relatedполучаетHttpRequestи должен возвращать логическое значение или список, как это делаетModelAdmin.list_select_related.
-
ModelAdmin.get_search_fields(request)[источник] -
Метод
get_search_fieldsполучаетHttpRequestи должен возвращать последовательность того же типа, что и для атрибутаsearch_fields.
-
ModelAdmin.get_sortable_by(request) -
Метод
get_sortable_by()получаетHttpRequestи должен возвращать коллекцию (например,list,tupleилиset) имён полей, по которым можно сортировать на странице списка изменений.По умолчанию метод возвращает
sortable_by, если он задан; в противном случае метод используетget_list_display().Например, чтобы запретить сортировку по одному или нескольким столбцам:
class PersonAdmin(admin.ModelAdmin): def get_sortable_by(self, request): return {*self.get_list_display(request)} - {"rank"}
-
ModelAdmin.get_inline_instances(request, obj=None)[источник] -
Метод
get_inline_instancesполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращатьlistилиtupleобъектовInlineModelAdmin, как описано ниже в разделеInlineModelAdmin. Например, следующий код возвращает встроенные формы без фильтрации по умолчанию на основе разрешений на добавление, изменение, удаление и просмотр:class MyModelAdmin(admin.ModelAdmin): inlines = [MyInline] def get_inline_instances(self, request, obj=None): return [inline(self.model, self.admin_site) for inline in self.inlines]Если вы переопределяете этот метод, убедитесь, что возвращаемые встроенные формы являются экземплярами классов, определённых в
inlines, иначе при добавлении связанных объектов может возникнуть ошибка «Bad Request».
-
ModelAdmin.get_inlines(request, obj) -
Метод
get_inlinesполучаетHttpRequestи редактируемыйobj(илиNoneв форме добавления) и должен возвращать итерируемый объект со встроенными формами. Можно переопределить этот метод, чтобы динамически добавлять встроенные формы в зависимости от запроса или экземпляра модели, вместо того чтобы указывать их вModelAdmin.inlines.
-
ModelAdmin.get_urls()[источник] -
Метод
get_urlsобъектаModelAdminвозвращает URL-адреса, используемые для этого ModelAdmin, аналогично URLconf. Поэтому их можно расширить, как описано в разделе Диспетчер URL-адресов, используя обёрткуAdminSite.admin_view()для представлений:from django.contrib import admin from django.template.response import TemplateResponse from django.urls import path class MyModelAdmin(admin.ModelAdmin): def get_urls(self): urls = super().get_urls() my_urls = [path("my_view/", self.admin_site.admin_view(self.my_view))] return my_urls + urls def my_view(self, request): # ... context = dict( # Include common variables for rendering the admin template. self.admin_site.each_context(request), # Anything else you want in the context... key=value, ) return TemplateResponse(request, "sometemplate.html", context)Если вы хотите использовать макет административной панели, унаследуйте класс от
admin/base_site.html:{% extends "admin/base_site.html" %} {% block content %} ... {% endblock %}Примечание
Обратите внимание, что функция
self.my_viewобёрнута вself.admin_site.admin_view. Это важно, поскольку обеспечивает два условия:- Выполняются проверки разрешений, гарантирующие, что доступ к представлению есть только у активных сотрудников.
- Применяется декоратор
django.views.decorators.cache.never_cache(), предотвращающий кэширование и гарантирующий актуальность возвращаемой информации.
Примечание
Обратите внимание, что пользовательские шаблоны включаются до стандартных URL-адресов административной панели: шаблоны URL-адресов администратора очень широкие и соответствуют почти чему угодно, поэтому пользовательские URL-адреса обычно следует размещать перед встроенными.
В этом примере доступ к
my_viewбудет осуществляться по адресу/admin/myapp/mymodel/my_view/(при условии, что URL-адреса административной панели включены в/admin/.)Если страницу можно кэшировать, но при этом требуется выполнять проверку разрешений, можно передать аргумент
cacheable=TrueвAdminSite.admin_view():path("my_view/", self.admin_site.admin_view(self.my_view, cacheable=True))Представления
ModelAdminимеют атрибутыmodel_admin. Другие представленияAdminSiteимеют атрибутыadmin_site.
-
ModelAdmin.get_form(request, obj=None, **kwargs)[источник] -
Возвращает класс
ModelFormдля использования в представлениях добавления и изменения административной панели; см.add_view()иchange_view().Базовая реализация использует
modelform_factory()для создания подклассаform, изменённого такими атрибутами, какfieldsиexclude. Например, если требуется предоставить суперпользователям дополнительные поля, можно заменить базовую форму следующим образом:class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): if request.user.is_superuser: kwargs["form"] = MySuperuserForm return super().get_form(request, obj, **kwargs)Также можно напрямую вернуть пользовательский класс
ModelForm.
-
ModelAdmin.get_formsets_with_inlines(request, obj=None)[источник] -
Выдаёт пары (
FormSet,InlineModelAdmin) для использования в представлениях добавления и изменения административной панели.Например, если требуется отображать определённую встроенную форму только в представлении изменения, можно переопределить
get_formsets_with_inlinesследующим образом:class MyModelAdmin(admin.ModelAdmin): inlines = [MyInline, SomeOtherInline] def get_formsets_with_inlines(self, request, obj=None): for inline in self.get_inline_instances(request, obj): # hide MyInline in the add view if not isinstance(inline, MyInline) or obj is not None: yield inline.get_formset(request, obj), inline
-
ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs) -
Метод
formfield_for_foreignkeyклассаModelAdminпозволяет переопределить стандартное поле формы для поля внешнего ключа. Например, чтобы возвращать подмножество объектов для этого поля внешнего ключа в зависимости от пользователя:class MyModelAdmin(admin.ModelAdmin): def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "car": kwargs["queryset"] = Car.objects.filter(owner=request.user) return super().formfield_for_foreignkey(db_field, request, **kwargs)В этом примере экземпляр
HttpRequestиспользуется для фильтрации поля внешнего ключаCar, чтобы отображались только автомобили, принадлежащие экземпляруUser.Для более сложной фильтрации можно использовать метод
ModelForm.__init__(), чтобы фильтровать поinstanceмодели (см. Поля для работы со связями). Например:class CountryAdminForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["capital"].queryset = self.instance.cities.all() class CountryAdmin(admin.ModelAdmin): form = CountryAdminForm
-
ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs) -
Как и метод
formfield_for_foreignkey, методformfield_for_manytomanyможно переопределить, чтобы изменить стандартное поле формы для поля «многие ко многим». Например, если владелец может владеть несколькими автомобилями, а автомобили могут принадлежать нескольким владельцам — то есть используется связь «многие ко многим», — можно отфильтровать поле внешнего ключаCar, чтобы отображались только автомобили, принадлежащиеUser:class MyModelAdmin(admin.ModelAdmin): def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == "cars": kwargs["queryset"] = Car.objects.filter(owner=request.user) return super().formfield_for_manytomany(db_field, request, **kwargs)
-
ModelAdmin.formfield_for_choice_field(db_field, request, **kwargs) -
Как и методы
formfield_for_foreignkeyиformfield_for_manytomany, методformfield_for_choice_fieldможно переопределить, чтобы изменить стандартное поле формы для поля с объявленными вариантами выбора. Например, если варианты выбора для суперпользователя должны отличаться от вариантов для обычных сотрудников, можно поступить следующим образом:class MyModelAdmin(admin.ModelAdmin): def formfield_for_choice_field(self, db_field, request, **kwargs): if db_field.name == "status": kwargs["choices"] = [ ("accepted", "Accepted"), ("denied", "Denied"), ] if request.user.is_superuser: kwargs["choices"].append(("ready", "Ready for deployment")) return super().formfield_for_choice_field(db_field, request, **kwargs)Ограничения
choicesЛюбой атрибут
choices, заданный для поля формы, будет действовать только для этого поля формы. Если для соответствующего поля модели заданы варианты выбора, варианты, предоставляемые форме, должны быть допустимым подмножеством этих вариантов; в противном случае отправка формы завершится ошибкойValidationErrorпри проверке модели перед сохранением.
-
ModelAdmin.get_changelist(request, **kwargs)[источник] -
Возвращает класс
Changelistдля отображения списка. По умолчанию используетсяdjango.contrib.admin.views.main.ChangeList. Наследуя этот класс, можно изменить поведение списка.
-
ModelAdmin.get_changelist_form(request, **kwargs)[источник] -
Возвращает класс
ModelFormдля использования вFormsetна странице списка изменений. Например, чтобы использовать пользовательскую форму:from django import forms class MyForm(forms.ModelForm): pass class MyModelAdmin(admin.ModelAdmin): def get_changelist_form(self, request, **kwargs): return MyForm
-
ModelAdmin.get_changelist_formset(request, **kwargs)[источник] -
Возвращает класс ModelFormSet для использования на странице списка изменений, если используется
list_editable. Например, чтобы использовать пользовательский набор форм:from django.forms import BaseModelFormSet class MyAdminFormSet(BaseModelFormSet): pass class MyModelAdmin(admin.ModelAdmin): def get_changelist_formset(self, request, **kwargs): kwargs["formset"] = MyAdminFormSet return super().get_changelist_formset(request, **kwargs)
-
ModelAdmin.lookup_allowed(lookup, value, request) -
Объекты на странице списка изменений можно фильтровать с помощью условий поиска из строки запроса URL. Например, так работает
list_filter. Условия поиска похожи на те, что используются вQuerySet.filter()(например,user__email=user@example.com). Поскольку пользователь может изменять условия поиска в строке запроса, их необходимо проверять, чтобы предотвратить несанкционированное раскрытие данных.Метод
lookup_allowed()получает путь условия поиска из строки запроса (например,'user__email'), соответствующее значение (например,'user@example.com') и запрос, а затем возвращает логическое значение, указывающее, разрешена ли фильтрацияQuerySetсписка изменений с использованием этих параметров. Еслиlookup_allowed()возвращаетFalse, вызываетсяDisallowedModelAdminLookup(подклассSuspiciousOperation).По умолчанию
lookup_allowed()разрешает доступ к локальным полям модели, путям полей, используемым вlist_filter(но не к путям изget_list_filter()), а также к условиям поиска, необходимым для правильной работыlimit_choices_toвraw_id_fields.Переопределите этот метод, чтобы настроить допустимые условия поиска для подкласса
ModelAdmin.
-
ModelAdmin.has_view_permission(request, obj=None) -
Должен возвращать
True, если просмотрobjразрешен, иFalseв противном случае. Если obj равенNone, метод должен возвращатьTrueилиFalse, чтобы указать, разрешен ли в целом просмотр объектов этого типа (например,Falseбудет означать, что текущему пользователю не разрешен просмотр ни одного объекта этого типа).Реализация по умолчанию возвращает
True, если у пользователя есть разрешение «change» или «view».
-
ModelAdmin.has_add_permission(request) -
Должен возвращать
True, если добавление объекта разрешено, иFalseв противном случае.
-
ModelAdmin.has_change_permission(request, obj=None) -
Должен возвращать
True, если редактированиеobjразрешено, иFalseв противном случае. ЕслиobjравенNone, метод должен возвращатьTrueилиFalse, чтобы указать, разрешено ли в целом редактирование объектов этого типа (например,Falseбудет означать, что текущему пользователю не разрешено редактировать ни один объект этого типа).
-
ModelAdmin.has_delete_permission(request, obj=None) -
Должен возвращать
True, если удалениеobjразрешено, иFalseв противном случае. ЕслиobjравенNone, метод должен возвращатьTrueилиFalse, чтобы указать, разрешено ли в целом удаление объектов этого типа (например,Falseбудет означать, что текущему пользователю не разрешено удалять ни один объект этого типа).
-
ModelAdmin.has_module_permission(request) -
Должен возвращать
True, если отображение модуля на главной странице административного сайта и доступ к главной странице модуля разрешены, иFalseв противном случае. По умолчанию используетUser.has_module_perms(). Переопределение этого метода не ограничивает доступ к представлениям просмотра, добавления, изменения или удаления; для этого следует использоватьhas_view_permission(),has_add_permission(),has_change_permission()иhas_delete_permission().
-
ModelAdmin.get_queryset(request) -
Метод
get_querysetобъектаModelAdminвозвращаетQuerySetвсех экземпляров модели, которые можно редактировать через административный сайт. Один из примеров использования переопределения этого метода — отображение объектов, принадлежащих вошедшему в систему пользователю:class MyModelAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) if request.user.is_superuser: return qs return qs.filter(author=request.user)
-
ModelAdmin.message_user(request, message, level=messages.INFO, extra_tags='', fail_silently=False)[источник] -
Отправляет пользователю сообщение с помощью бэкенда
django.contrib.messages. См. пример пользовательского ModelAdmin.Именованные аргументы позволяют изменить уровень сообщения, добавить дополнительные CSS-классы или не сообщать об ошибке, если фреймворк
contrib.messagesне установлен. Эти именованные аргументы соответствуют аргументамdjango.contrib.messages.add_message(); подробности см. в документации этой функции. Отличие заключается в том, что уровень можно передать строковой меткой, а не только целым числом или константой.
-
ModelAdmin.get_paginator(request, queryset, per_page, orphans=0, allow_empty_first_page=True)[источник] -
Возвращает экземпляр пагинатора, который следует использовать для этого представления. По умолчанию создает экземпляр
paginator.
-
ModelAdmin.response_add(request, obj, post_url_continue=None)[источник] -
Определяет
HttpResponseдля этапаadd_view().response_addвызывается после отправки формы административного интерфейса, сразу после создания и сохранения объекта и всех связанных экземпляров. Вы можете переопределить этот метод, чтобы изменить поведение по умолчанию после создания объекта.
-
ModelAdmin.response_change(request, obj)[источник] -
Определяет
HttpResponseдля этапаchange_view().response_changeвызывается после отправки формы административного интерфейса, сразу после сохранения объекта и всех связанных экземпляров. Вы можете переопределить этот метод, чтобы изменить поведение по умолчанию после изменения объекта.
-
ModelAdmin.response_delete(request, obj_display, obj_id)[источник] -
Определяет
HttpResponseдля этапаdelete_view().response_deleteвызывается после удаления объекта. Вы можете переопределить этот метод, чтобы изменить поведение по умолчанию после удаления объекта.obj_display— это строка с именем удаленного объекта.obj_id— это сериализованный идентификатор, используемый для получения объекта, который необходимо удалить.
-
ModelAdmin.get_formset_kwargs(request, obj, inline, prefix)[источник] -
Метод-перехватчик для настройки именованных аргументов, передаваемых конструктору набора форм. Например, чтобы передать
requestформам набора форм:class MyModelAdmin(admin.ModelAdmin): def get_formset_kwargs(self, request, obj, inline, prefix): return { **super().get_formset_kwargs(request, obj, inline, prefix), "form_kwargs": {"request": request}, }Также его можно использовать, чтобы задать
initialдля форм набора форм.
-
ModelAdmin.get_changeform_initial_data(request)[источник] -
Метод-перехватчик для задания начальных данных в формах изменения административного интерфейса. По умолчанию начальные значения полей берутся из параметров
GET. Например,?name=initial_valueзадаст начальное значение поляnameравнымinitial_value.Этот метод должен возвращать словарь вида
{'fieldname': 'fieldval'}:def get_changeform_initial_data(self, request): return {"name": "custom_initial_value"}
-
ModelAdmin.get_deleted_objects(objs, request)[источник] -
Метод-перехватчик для настройки процесса удаления в
delete_view()и действия «удалить выбранные».Аргумент
objs— это однородный итерируемый объект с элементами для удаления (QuerySetили список экземпляров модели), аrequest— этоHttpRequest.Этот метод должен возвращать кортеж из четырех элементов
(deleted_objects, model_count, perms_needed, protected).deleted_objects— это список строк, представляющих все объекты, которые будут удалены. Если есть связанные объекты, которые также нужно удалить, список будет вложенным и будет содержать эти связанные объекты. Список форматируется в шаблоне с помощью фильтраunordered_list.model_count— это словарь, сопоставляющийverbose_name_pluralкаждой модели с количеством объектов, которые будут удалены.perms_needed— это множество значенийverbose_nameмоделей, объекты которых пользователь не имеет права удалять.protected— это список строк, представляющих все защищенные связанные объекты, которые нельзя удалить. Список отображается в шаблоне.
Другие методы
-
ModelAdmin.add_view(request, form_url='', extra_context=None)[источник] -
Представление Django для страницы добавления экземпляра модели. См. примечание ниже.
-
ModelAdmin.change_view(request, object_id, form_url='', extra_context=None)[источник] -
Представление Django для страницы редактирования экземпляра модели. См. примечание ниже.
-
ModelAdmin.changelist_view(request, extra_context=None)[источник] -
Представление Django для страницы списка изменений/действий экземпляров модели. См. примечание ниже.
-
ModelAdmin.delete_view(request, object_id, extra_context=None)[источник] -
Представление Django для страницы подтверждения удаления экземпляра (экземпляров) модели. См. примечание ниже.
-
ModelAdmin.history_view(request, object_id, extra_context=None)[источник] -
Представление Django для страницы с историей изменений указанного экземпляра модели.
В отличие от методов ModelAdmin, которые служат точками расширения и описаны в предыдущем разделе, эти пять методов фактически предназначены для вызова в качестве представлений Django обработчиком диспетчеризации URL-адресов административного приложения, чтобы отображать страницы для операций CRUD с экземплярами модели. Поэтому полное переопределение этих методов существенно изменит поведение административного приложения.
Одна из распространенных причин переопределения этих методов — расширение данных контекста, передаваемых шаблону, который отображает представление. В следующем примере переопределяется представление изменения, чтобы в отображаемый шаблон передавались дополнительные данные сопоставления, которые иначе были бы недоступны:
class MyModelAdmin(admin.ModelAdmin):
# A template for a very customized change view:
change_form_template = "admin/myapp/extras/openstreetmap_change_form.html"
def get_osm_info(self):
# ...
pass
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["osm_data"] = self.get_osm_info()
return super().change_view(
request,
object_id,
form_url,
extra_context=extra_context,
)
Эти представления возвращают экземпляры TemplateResponse, позволяющие легко настроить данные ответа перед его отображением. Подробнее см. в документации по TemplateResponse.
ModelAdmin определения ресурсов
Иногда бывает нужно добавить немного CSS и/или JavaScript на страницы добавления/изменения. Это можно сделать с помощью внутреннего класса Media в ModelAdmin:
class ArticleAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ["my_styles.css"],
}
js = ["my_code.js"]
Приложение staticfiles добавляет STATIC_URL (или MEDIA_URL, если STATIC_URL равен None) перед путями к ресурсам. Действуют те же правила, что и для обычных определений ресурсов в формах.
jQuery
JavaScript административного интерфейса Django использует библиотеку jQuery.
Чтобы избежать конфликтов со скриптами или библиотеками, предоставленными пользователями, jQuery Django (версия 3.7.1) имеет пространство имен django.jQuery. Если вы хотите использовать jQuery в собственном JavaScript административного интерфейса, не подключая вторую копию, можно использовать объект django.jQuery на страницах списков и добавления/редактирования. Кроме того, собственные формы или виджеты административного интерфейса, зависящие от django.jQuery, должны указывать js=['admin/js/jquery.init.js', …] при объявлении ресурсов формы.
Класс ModelAdmin по умолчанию требует jQuery, поэтому добавлять jQuery в список медиа-ресурсов ModelAdmin не нужно, если в этом нет особой необходимости. Например, если библиотека jQuery должна находиться в глобальном пространстве имен (например, при использовании сторонних плагинов jQuery) или если вам нужна более новая версия jQuery, необходимо подключить собственную копию.
Django предоставляет несжатую и «минифицированную» версии jQuery: соответственно, jquery.js и jquery.min.js.
Классы ModelAdmin и InlineModelAdmin имеют свойство media, возвращающее список объектов Media, в которых хранятся пути к JavaScript-файлам форм и/или наборов форм. Если DEBUG равно True, будут возвращены несжатые версии различных JavaScript-файлов, включая jquery.js; в противном случае будут возвращены «минифицированные» версии.
Добавление пользовательской проверки данных в административный интерфейс
В административном интерфейсе также можно добавить пользовательскую проверку данных. Автоматический административный интерфейс повторно использует django.forms, а класс ModelAdmin позволяет определить собственную форму:
class ArticleAdmin(admin.ModelAdmin):
form = MyArticleAdminForm
MyArticleAdminForm можно определить в любом месте, если импортировать его там, где это необходимо. Затем в форме можно добавить собственную проверку любого поля:
class MyArticleAdminForm(forms.ModelForm):
def clean_name(self):
# do something that validates your data
return self.cleaned_data["name"]
Здесь важно использовать ModelForm, иначе могут возникнуть проблемы. Дополнительные сведения см. в документации по формам, в разделе о пользовательской проверке данных и, в частности, в примечаниях о проверке ModelForm.
InlineModelAdmin — объекты
-
class InlineModelAdmin
-
class TabularInline[исходный код]
-
class StackedInline[исходный код] -
Интерфейс администратора позволяет редактировать модели на той же странице, что и родительскую модель. Такие объекты называются встроенными формами (inlines). Предположим, у вас есть две модели:
from django.db import models class Author(models.Model): name = models.CharField(max_length=100) class Book(models.Model): author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=100)Вы можете редактировать книги, написанные автором, на странице автора. Чтобы добавить встроенные формы к модели, укажите их в
ModelAdmin.inlines:from django.contrib import admin from myapp.models import Author, Book class BookInline(admin.TabularInline): model = Book class AuthorAdmin(admin.ModelAdmin): inlines = [ BookInline, ] admin.site.register(Author, AuthorAdmin)Django предоставляет два подкласса
InlineModelAdmin:Разница между ними заключается лишь в шаблоне, используемом для их отображения.
InlineModelAdmin — параметры
InlineModelAdmin имеет многие те же возможности, что и ModelAdmin, а также добавляет некоторые собственные (общие возможности определены в суперклассе BaseModelAdmin). К общим возможностям относятся:
formfieldsetsfieldsformfield_overridesexcludefilter_horizontalfilter_verticalorderingprepopulated_fieldsget_fieldsets()get_queryset()radio_fieldsreadonly_fieldsraw_id_fieldsformfield_for_choice_field()formfield_for_foreignkey()formfield_for_manytomany()has_module_permission()
Класс InlineModelAdmin добавляет или настраивает:
-
InlineModelAdmin.model -
Модель, используемая встроенной формой. Этот параметр обязателен.
-
InlineModelAdmin.fk_name -
Имя внешнего ключа в модели. В большинстве случаев оно определяется автоматически, но
fk_nameнеобходимо указать явно, если существует несколько внешних ключей на одну и ту же родительскую модель.
-
InlineModelAdmin.formset -
По умолчанию используется
BaseInlineFormSet. Собственный набор форм предоставляет множество возможностей для настройки. Встроенные формы построены на основе наборов форм моделей.
-
InlineModelAdmin.form -
По умолчанию значением
formявляетсяModelForm. Это значение передаётся вinlineformset_factory()при создании набора форм для этой встроенной формы.
Предупреждение
При написании собственной проверки для форм InlineModelAdmin будьте осторожны с проверками, зависящими от свойств родительской модели. Если родительская модель не пройдёт проверку, она может остаться в некорректном состоянии, как описано в предупреждении в разделе Проверка в ModelForm.
-
InlineModelAdmin.classes -
Список или кортеж дополнительных CSS-классов, применяемых к набору полей, отображаемому для встроенных форм. По умолчанию используется
None. Как и для классов, заданных вfieldsets, встроенные формы с классомcollapseизначально будут свёрнуты; развернуть их можно с помощью раскрывающегося элемента.
-
InlineModelAdmin.extra -
Задаёт число дополнительных форм, которые будут отображаться в наборе форм сверх начальных форм. По умолчанию — 3. Подробности см. в документации по наборам форм.
Для пользователей с включённым JavaScript браузером отображается ссылка «Добавить ещё», позволяющая добавлять любое количество дополнительных встроенных форм сверх тех, которые создаются на основе аргумента
extra.Динамическая ссылка не будет отображаться, если количество уже отображаемых форм превышает
max_numили если у пользователя отключён JavaScript.Метод
InlineModelAdmin.get_extra()также позволяет настроить количество дополнительных форм.
-
InlineModelAdmin.max_num -
Задаёт максимальное количество форм, отображаемых во встроенной форме. Это значение не обязательно соответствует количеству объектов, но может ему соответствовать, если значение достаточно мало. Подробности см. в разделе Ограничение количества редактируемых объектов.
Метод
InlineModelAdmin.get_max_num()также позволяет настроить максимальное количество дополнительных форм.
-
InlineModelAdmin.min_num -
Задаёт минимальное количество форм, отображаемых во встроенной форме. Подробности см. в
modelformset_factory().Метод
InlineModelAdmin.get_min_num()также позволяет настроить минимальное количество отображаемых форм.
-
InlineModelAdmin.raw_id_fields -
По умолчанию интерфейс администратора Django использует для полей, являющихся
ForeignKey, выпадающий список (<select>). Иногда нежелательно загружать все связанные объекты для отображения в этом списке.raw_id_fields— это список полей, для которых вы хотите использовать виджетInputвместо обычного виджета дляForeignKeyилиManyToManyField:class BookInline(admin.TabularInline): model = Book raw_id_fields = ["pages"]
-
InlineModelAdmin.template -
Шаблон, используемый для отображения встроенной формы на странице.
-
InlineModelAdmin.verbose_name -
Переопределение значения
verbose_nameиз внутреннего классаMetaмодели.
-
InlineModelAdmin.verbose_name_plural -
Переопределение значения
verbose_name_pluralиз внутреннего классаMetaмодели. Если это значение не задано, но определеноInlineModelAdmin.verbose_name, Django будет использоватьInlineModelAdmin.verbose_name+'s'.
-
InlineModelAdmin.can_delete -
Определяет, можно ли удалять объекты встроенной формы. По умолчанию —
True.
-
InlineModelAdmin.show_change_link -
Определяет, будут ли у объектов встроенной формы, которые можно изменять в интерфейсе администратора, ссылки на форму изменения. По умолчанию —
False.
-
InlineModelAdmin.get_formset(request, obj=None, **kwargs) -
Возвращает класс
BaseInlineFormSetдля использования в представлениях добавления и изменения в интерфейсе администратора.obj— редактируемый родительский объект илиNoneпри добавлении нового родительского объекта. См. пример дляModelAdmin.get_formsets_with_inlines.
-
InlineModelAdmin.get_extra(request, obj=None, **kwargs) -
Возвращает количество дополнительных форм для встроенной формы. По умолчанию возвращает атрибут
InlineModelAdmin.extra.Переопределите этот метод, чтобы программно определять количество дополнительных форм для встроенной формы. Например, это значение может зависеть от экземпляра модели (передаваемого как именованный аргумент
obj):class BinaryTreeAdmin(admin.TabularInline): model = BinaryTree def get_extra(self, request, obj=None, **kwargs): extra = 2 if obj: return extra - obj.binarytree_set.count() return extra
-
InlineModelAdmin.get_max_num(request, obj=None, **kwargs) -
Возвращает максимальное количество дополнительных форм для встроенной формы. По умолчанию возвращает атрибут
InlineModelAdmin.max_num.Переопределите этот метод, чтобы программно определять максимальное количество форм для встроенной формы. Например, это значение может зависеть от экземпляра модели (передаваемого как именованный аргумент
obj):class BinaryTreeAdmin(admin.TabularInline): model = BinaryTree def get_max_num(self, request, obj=None, **kwargs): max_num = 10 if obj and obj.parent: return max_num - 5 return max_num
-
InlineModelAdmin.get_min_num(request, obj=None, **kwargs) -
Возвращает минимальное количество форм для встроенной формы. По умолчанию возвращает атрибут
InlineModelAdmin.min_num.Переопределите этот метод, чтобы программно определять минимальное количество форм для встроенной формы. Например, это значение может зависеть от экземпляра модели (передаваемого как именованный аргумент
obj).
-
InlineModelAdmin.has_add_permission(request, obj) -
Должен возвращать
True, если добавление объекта встроенной формы разрешено, иFalseв противном случае.obj— редактируемый родительский объект илиNoneпри добавлении нового родительского объекта.
-
InlineModelAdmin.has_change_permission(request, obj=None) -
Должен возвращать
True, если редактирование объекта встроенной формы разрешено, иFalseв противном случае.obj— редактируемый родительский объект.
-
InlineModelAdmin.has_delete_permission(request, obj=None) -
Должен возвращать
True, если удаление объекта встроенной формы разрешено, иFalseв противном случае.obj— редактируемый родительский объект.
Примечание
Аргумент obj, передаваемый методам InlineModelAdmin, — это редактируемый родительский объект или None при добавлении нового родительского объекта.
Работа с моделью, содержащей два или более внешних ключа на одну родительскую модель
Иногда модель может содержать несколько внешних ключей на одну и ту же модель. Например, возьмём такую модель:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Friendship(models.Model):
to_person = models.ForeignKey(
Person, on_delete=models.CASCADE, related_name="friends"
)
from_person = models.ForeignKey(
Person, on_delete=models.CASCADE, related_name="from_friends"
)
Если вы хотите отобразить встроенную форму на страницах добавления или изменения Person в интерфейсе администратора, необходимо явно определить внешний ключ, поскольку Django не может сделать это автоматически:
from django.contrib import admin
from myapp.models import Friendship, Person
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
admin.site.register(Person, PersonAdmin)
Работа с моделями «многие-ко-многим»
По умолчанию виджеты администратора для связей «многие-ко-многим» отображаются в модели, содержащей фактическую ссылку на ManyToManyField. В зависимости от определения ModelAdmin каждое поле «многие-ко-многим» в модели будет представлено стандартным HTML-элементом <select multiple>, горизонтальным или вертикальным фильтром либо виджетом raw_id_fields. Однако эти виджеты также можно заменить встроенными формами.
Предположим, у нас есть следующие модели:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, related_name="groups")
Чтобы отображать связи «многие-ко-многим» с помощью встроенной формы, можно определить для связи объект InlineModelAdmin:
from django.contrib import admin
from myapp.models import Group
class MembershipInline(admin.TabularInline):
model = Group.members.through
class GroupAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
exclude = ["members"]
admin.site.register(Group, GroupAdmin)
В этом примере стоит отметить две особенности.
Во-первых, класс MembershipInline ссылается на Group.members.through. Атрибут through указывает на модель, которая управляет связью «многие-ко-многим». Django автоматически создаёт эту модель при определении поля «многие-ко-многим».
Во-вторых, в GroupAdmin необходимо вручную исключить поле members. Django отображает виджет администратора для поля «многие-ко-многим» в модели, которая определяет связь (в данном случае — Group). Если вы хотите представить связь «многие-ко-многим» с помощью встроенной модели, необходимо указать интерфейсу администратора Django не отображать этот виджет — иначе на странице администратора окажутся два виджета для управления связью.
Обратите внимание: при использовании этого приёма сигналы m2m_changed не вызываются. Это происходит потому, что с точки зрения интерфейса администратора through — просто модель с двумя полями внешнего ключа, а не связь «многие-ко-многим».
Во всех остальных отношениях InlineModelAdmin ничем не отличается от любой другой. Её внешний вид можно настроить с помощью обычных свойств ModelAdmin.
Работа с промежуточными моделями «многие-ко-многим»
Если указать промежуточную модель с помощью аргумента through в ManyToManyField, интерфейс администратора по умолчанию не будет отображать виджет. Это связано с тем, что для каждого экземпляра такой промежуточной модели требуется больше информации, чем можно отобразить в одном виджете, а требуемое расположение нескольких виджетов зависит от промежуточной модели.
Однако мы всё же хотим иметь возможность редактировать эти данные во встроенной форме. К счастью, это можно сделать с помощью встроенных моделей администратора. Предположим, у нас есть следующие модели:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through="Membership")
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["person", "group"], name="unique_person_group"
)
]
Сначала для отображения этой промежуточной модели в интерфейсе администратора определим класс встроенной формы для модели Membership:
class MembershipInline(admin.TabularInline):
model = Membership
extra = 1
В этом примере используются значения InlineModelAdmin по умолчанию для модели Membership, а количество дополнительных форм добавления ограничено одной. Настроить это можно с помощью любых параметров, доступных классам InlineModelAdmin.
Теперь создайте представления администратора для моделей Person и Group:
class PersonAdmin(admin.ModelAdmin):
inlines = [MembershipInline]
class GroupAdmin(admin.ModelAdmin):
inlines = [MembershipInline]
Наконец, зарегистрируйте модели Person и Group на сайте администратора:
admin.site.register(Person, PersonAdmin) admin.site.register(Group, GroupAdmin)
Теперь сайт администратора настроен для редактирования объектов Membership во встроенной форме как на страницах сведений Person, так и Group.
Использование универсальных связей во встроенной форме
Встроенную форму можно использовать с объектами, связанными универсальной связью. Предположим, у вас есть следующие модели:
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Image(models.Model):
image = models.ImageField(upload_to="images")
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey("content_type", "object_id")
class Product(models.Model):
name = models.CharField(max_length=100)
Чтобы разрешить редактирование и создание экземпляра Image в представлениях добавления и изменения Product, используйте GenericTabularInline или GenericStackedInline (оба класса являются подклассами GenericInlineModelAdmin), предоставляемые модулем admin. Они реализуют соответственно табличное и блочное визуальное представление форм для встроенных объектов, как и их аналоги без универсальных связей. Они ведут себя так же, как любые другие встроенные формы. В admin.py для этого примера приложения:
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from myapp.models import Image, Product
class ImageInline(GenericTabularInline):
model = Image
class ProductAdmin(admin.ModelAdmin):
inlines = [
ImageInline,
]
admin.site.register(Product, ProductAdmin)
Более подробную информацию см. в документации по contenttypes.
Переопределение шаблонов администратора
Вы можете переопределить многие шаблоны, которые модуль администратора использует для создания различных страниц сайта администратора. Некоторые из них можно переопределить для конкретного приложения или модели.
Настройка каталогов шаблонов администратора проекта
Файлы шаблонов администратора находятся в каталоге django/contrib/admin/templates/admin.
Чтобы переопределить один или несколько из них, сначала создайте каталог admin в каталоге templates вашего проекта. Это может быть любой из каталогов, указанных в параметре DIRS серверной части DjangoTemplates в настройке TEMPLATES. Если вы настроили параметр 'loaders', убедитесь, что 'django.template.loaders.filesystem.Loader' указан перед 'django.template.loaders.app_directories.Loader', чтобы система загрузки шаблонов находила ваши шаблоны раньше шаблонов, входящих в состав django.contrib.admin.
Внутри этого каталога admin создайте подкаталоги с именами ваших приложений. Внутри них создайте подкаталоги с именами моделей. Обратите внимание: при поиске каталога приложение администратора преобразует имя модели в нижний регистр, поэтому, если ваше приложение будет работать в файловой системе с учётом регистра, назовите каталог полностью строчными буквами.
Чтобы переопределить шаблон администратора для конкретного приложения, скопируйте шаблон из каталога django/contrib/admin/templates/admin, внесите изменения и сохраните его в одном из созданных каталогов.
Например, если мы хотим добавить инструмент в представление списка изменений для всех моделей приложения с именем my_app, нужно скопировать contrib/admin/templates/admin/change_list.html в каталог templates/admin/my_app/ нашего проекта и внести необходимые изменения.
Если мы хотим добавить инструмент в представление списка изменений только для конкретной модели с именем «Page», нужно скопировать тот же файл в каталог templates/admin/my_app/page нашего проекта.
Переопределение и замена шаблона администратора
Благодаря модульной структуре шаблонов администратора обычно нет необходимости и не рекомендуется заменять шаблон целиком. Почти всегда лучше переопределить только тот раздел шаблона, который требуется изменить.
Продолжим предыдущий пример: мы хотим добавить новую ссылку рядом с инструментом History для модели Page. Изучив change_form.html, мы выяснили, что нужно переопределить только блок object-tools-items. Поэтому наш новый шаблон change_form.html будет выглядеть так:
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
<li>
<a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% translate "History" %}</a>
</li>
<li>
<a href="mylink/" class="historylink">My Link</a>
</li>
{% if has_absolute_url %}
<li>
<a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% translate "View on site" %}</a>
</li>
{% endif %}
{% endblock %}
Вот и всё! Если мы разместим этот файл в каталоге templates/admin/my_app, ссылка появится на форме изменения всех моделей приложения my_app.
Шаблоны, которые можно переопределить для приложения или модели
Не каждый шаблон в contrib/admin/templates/admin можно переопределить отдельно для приложения или модели. К таким шаблонам относятся:
actions.htmlapp_index.htmlchange_form.htmlchange_form_object_tools.htmlchange_list.htmlchange_list_object_tools.htmlchange_list_results.htmldate_hierarchy.htmldelete_confirmation.htmlobject_history.htmlpagination.htmlpopup_response.htmlprepopulated_fields_js.htmlsearch_form.htmlsubmit_line.html
Шаблоны, которые нельзя переопределить таким способом, всё ещё можно переопределить для всего проекта: поместите новую версию в каталог templates/admin. Это особенно полезно для создания собственных страниц ошибок 404 и 500.
Примечание
Некоторые шаблоны администратора, например change_list_results.html, используются для отображения пользовательских тегов включения. Их можно переопределить, однако в таких случаях, вероятно, лучше создать собственную версию соответствующего тега и присвоить ей другое имя. Так вы сможете использовать его выборочно.
Шаблоны главной страницы и входа
Если вы хотите изменить шаблоны главной страницы, входа или выхода, лучше создать собственный экземпляр AdminSite (см. ниже) и изменить свойства AdminSite.index_template , AdminSite.login_template или AdminSite.logout_template.
Поддержка тем оформления
Для определения цветов и шрифтов интерфейс администратора использует переменные CSS. Благодаря этому тему можно изменить, не переопределяя множество отдельных правил CSS. Например, если вы предпочитаете фиолетовый цвет синему, можно добавить в проект переопределение шаблона admin/base.html:
{% extends 'admin/base.html' %}
{% block extrastyle %}{{ block.super }}
<style>
html[data-theme="light"], :root {
--primary: #9774d5;
--secondary: #785cab;
--link-fg: #7c449b;
--link-selected-fg: #8f5bb2;
}
</style>
{% endblock %}
Список переменных CSS определён в файле django/contrib/admin/static/admin/css/base.css.
Переменные тёмного режима, учитывающие медиазапрос prefers-color-scheme, определены в файле django/contrib/admin/static/admin/css/dark_mode.css. Этот файл подключается к документу в {% block dark-mode-vars %}.
extrabody — блок
Вы можете добавить пользовательский HTML, JavaScript или другое содержимое, которое будет отображаться непосредственно перед закрывающим тегом </body> шаблонов, расширяющих admin/base.html, переопределив блок extrabody. Например, если при загрузке страницы должно появляться предупреждение, можно добавить в проект переопределение шаблона admin/base.html:
{% extends 'admin/base.html' %}
{% block extrabody %}
{{ block.super }}
<script>
document.addEventListener('DOMContentLoaded', function() {
window.alert('Welcome!');
});
</script>
{% endblock extrabody %}
AdminSite объекты
-
class AdminSite(name='admin')[исходный код] -
Сайт администрирования Django представлен экземпляром
django.contrib.admin.sites.AdminSite; по умолчанию экземпляр этого класса создается какdjango.contrib.admin.site, и вы можете зарегистрировать в нем свои модели и экземплярыModelAdmin.Если вы хотите настроить сайт администрирования по умолчанию, вы можете переопределить его.
При создании экземпляра
AdminSiteвы можете указать уникальное имя экземпляра, передав аргументnameконструктору. Это имя используется для идентификации экземпляра, в частности при обратном разрешении URL-адресов админки. Если имя экземпляра не указано, будет использоваться имя экземпляра по умолчаниюadmin. Пример настройки класса Настройка класса AdminSite см. в разделеAdminSite.
-
django.contrib.admin.sites.all_sites -
WeakSetсодержит все экземпляры сайта администрирования.
AdminSite атрибуты
Шаблоны могут переопределять или расширять базовые шаблоны админки, как описано в разделе Переопределение шаблонов админки.
-
AdminSite.site_header -
Текст, отображаемый в верхней части каждой страницы админки, в виде
<div>(строки). По умолчанию это «Администрирование Django».
-
AdminSite.site_title -
Текст, отображаемый в конце
<title>каждой страницы админки (строка). По умолчанию это «Администрирование сайта Django».
-
AdminSite.site_url -
URL ссылки «Просмотреть сайт» в верхней части каждой страницы админки. По умолчанию
site_urlимеет значение/. Установите значениеNone, чтобы удалить ссылку.Для сайтов, работающих по подчиненному пути, метод
each_context()проверяет, задано ли в текущем запросе значениеrequest.META['SCRIPT_NAME'], и использует его, еслиsite_urlне задано в значение, отличное от/.
-
AdminSite.index_title -
Текст, отображаемый в верхней части главной страницы админки (строка). По умолчанию это «Администрирование сайта».
-
AdminSite.index_template -
Путь к пользовательскому шаблону, который будет использоваться главным представлением индекса сайта администрирования.
-
AdminSite.app_index_template -
Путь к пользовательскому шаблону, который будет использоваться представлением индекса приложения сайта администрирования.
-
AdminSite.empty_value_display -
Строка, используемая для отображения пустых значений в списке изменений сайта администрирования. По умолчанию используется тире. Значение также можно переопределить отдельно для каждого
ModelAdminи для пользовательского поля внутриModelAdmin, задав атрибутempty_value_displayдля поля. Примеры см. в разделеModelAdmin.empty_value_display.
-
Логическое значение, определяющее, следует ли показывать боковую панель навигации на больших экранах. По умолчанию установлено значение
True.
-
AdminSite.final_catch_all_view -
Логическое значение, определяющее, следует ли добавлять в админку заключительное универсальное представление, перенаправляющее не прошедших аутентификацию пользователей на страницу входа. По умолчанию установлено значение
True.Предупреждение
Не рекомендуется устанавливать значение
False, поскольку это представление защищает от потенциальной проблемы конфиденциальности, связанной с перебором моделей.
-
AdminSite.login_template -
Путь к пользовательскому шаблону, который будет использоваться представлением входа на сайт администрирования.
-
AdminSite.login_form -
Подкласс
AuthenticationForm, который будет использоваться представлением входа на сайт администрирования.
-
AdminSite.logout_template -
Путь к пользовательскому шаблону, который будет использоваться представлением выхода с сайта администрирования.
-
AdminSite.password_change_form -
Новое в Django 6.0.
Подкласс
PasswordChangeForm, который будет использоваться представлением смены пароля на сайте администрирования.
-
AdminSite.password_change_template -
Путь к пользовательскому шаблону, который будет использоваться представлением смены пароля на сайте администрирования.
-
AdminSite.password_change_done_template -
Путь к пользовательскому шаблону, который будет использоваться представлением завершения смены пароля на сайте администрирования.
AdminSite методы
-
AdminSite.each_context(request)[исходный код] -
Возвращает словарь переменных, которые нужно добавить в контекст шаблона для каждой страницы сайта администрирования.
По умолчанию включает следующие переменные и значения:
-
site_header:AdminSite.site_header -
site_title:AdminSite.site_title -
site_url:AdminSite.site_url -
has_permission:AdminSite.has_permission() -
available_apps: список приложений из реестра приложений, доступных текущему пользователю. Каждый элемент списка — это словарь, представляющий приложение со следующими ключами:-
app_label: метка приложения -
app_url: URL страницы индекса приложения в админке -
has_module_perms: логическое значение, указывающее, разрешены ли текущему пользователю просмотр и доступ к странице индекса модуля -
models: список моделей, доступных в приложении
Каждая модель представлена словарем со следующими ключами:
-
model: класс модели -
object_name: имя класса модели -
name: множественное имя модели -
perms:dictотслеживания разрешений наadd,change,deleteиview -
admin_url: URL списка изменений модели в админке -
add_url: URL админки для добавления нового экземпляра модели
-
-
is_popup: отображается ли текущая страница во всплывающем окне -
is_nav_sidebar_enabled:AdminSite.enable_nav_sidebar -
log_entries:AdminSite.get_log_entries()
-
-
AdminSite.get_app_list(request, app_label=None)[исходный код] -
Возвращает список приложений из реестра приложений, доступных текущему пользователю. Чтобы получить сведения об одном приложении, можно дополнительно передать аргумент
app_label. Каждый элемент списка — это словарь, представляющий приложение со следующими ключами:-
app_label: метка приложения -
app_url: URL страницы индекса приложения в админке -
has_module_perms: логическое значение, указывающее, разрешены ли текущему пользователю просмотр и доступ к странице индекса модуля -
models: список моделей, доступных в приложении -
name: имя приложения
Каждая модель представлена словарем со следующими ключами:
-
model: класс модели -
object_name: имя класса модели -
name: множественное имя модели -
perms:dictотслеживания разрешений наadd,change,deleteиview -
admin_url: URL списка изменений модели в админке -
add_url: URL админки для добавления нового экземпляра модели
Списки приложений и моделей сортируются по алфавиту в соответствии с их именами. Вы можете переопределить этот метод, чтобы изменить порядок по умолчанию на главной странице админки.
-
-
AdminSite.has_permission(request)[исходный код] -
Возвращает
True, если пользователь для заданногоHttpRequestимеет разрешение просматривать хотя бы одну страницу сайта администрирования. По умолчанию требуется, чтобы иUser.is_active, иUser.is_staffимели значениеTrue.
-
AdminSite.register(model_or_iterable, admin_class=None, **options)[исходный код] -
Регистрирует указанный класс модели (или итерируемый объект с классами) в заданном
admin_class. По умолчаниюadmin_classимеет значениеModelAdmin(параметры админки по умолчанию). Если переданы именованные аргументы, напримерlist_display, они будут применены как параметры класса админки.Вызывает
ImproperlyConfigured, если модель является абстрактной, иdjango.contrib.admin.exceptions.AlreadyRegistered, если модель уже зарегистрирована.
-
AdminSite.unregister(model_or_iterable)[исходный код] -
Отменяет регистрацию указанного класса модели (или итерируемого объекта с классами).
Вызывает
django.contrib.admin.exceptions.NotRegistered, если модель еще не зарегистрирована.
-
AdminSite.get_model_admin(model)[исходный код] -
Возвращает класс админки для указанного класса модели. Вызывает
django.contrib.admin.exceptions.NotRegistered, если модель не зарегистрирована.
-
AdminSite.get_log_entries(request)[исходный код] -
Возвращает queryset связанных экземпляров
LogEntry, отображаемых на главной странице сайта. Этот метод можно переопределить, чтобы фильтровать записи журнала по другим критериям.
Подключение экземпляров AdminSite к вашему URLconf
Последний шаг при настройке админки Django — подключить экземпляр AdminSite к вашему URLconf. Для этого направьте URL на метод AdminSite.urls. Использовать include() не требуется.
В этом примере мы регистрируем экземпляр AdminSite по умолчанию django.contrib.admin.site по URL /admin/
# urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path("admin/", admin.site.urls),
]
Настройка класса AdminSite
Если вы хотите создать собственный сайт администрирования с индивидуальным поведением, можете создать подкласс AdminSite и переопределить или добавить всё, что вам нужно. Затем создайте экземпляр подкласса AdminSite (так же, как создаете экземпляр любого другого класса Python) и зарегистрируйте в нем свои модели и подклассы ModelAdmin вместо регистрации на сайте по умолчанию. Наконец, измените myproject/urls.py, чтобы он ссылался на ваш подкласс AdminSite.
myapp/admin.pyfrom django.contrib import admin
from .models import MyModel
class MyAdminSite(admin.AdminSite):
site_header = "Monty Python administration"
admin_site = MyAdminSite(name="myadmin")
admin_site.register(MyModel)
myproject/urls.pyfrom django.urls import path
from myapp.admin import admin_site
urlpatterns = [
path("myadmin/", admin_site.urls),
]
Обратите внимание, что при использовании собственного экземпляра AdminSite вам может понадобиться отключить автоматическое обнаружение модулей admin, поскольку вы, вероятно, будете импортировать все модули admin отдельных приложений в свой модуль myproject.admin. Это означает, что в настройке INSTALLED_APPS нужно указать 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin'.
Переопределение сайта администрирования по умолчанию
Вы можете переопределить django.contrib.admin.site по умолчанию, задав для атрибута default_site пользовательского AppConfig путь импорта с точками к подклассу AdminSite или к вызываемому объекту, возвращающему экземпляр сайта.
myproject/admin.pyfrom django.contrib import admin class MyAdminSite(admin.AdminSite): ...
myproject/apps.pyfrom django.contrib.admin.apps import AdminConfig
class MyAdminConfig(AdminConfig):
default_site = "myproject.admin.MyAdminSite"
myproject/settings.pyINSTALLED_APPS = [
# ...
"myproject.apps.MyAdminConfig", # replaces 'django.contrib.admin'
# ...
]
Несколько сайтов администрирования в одном URLconf
На одном сайте, работающем на Django, можно создать несколько экземпляров сайта администрирования. Создайте несколько экземпляров AdminSite и разместите каждый по отдельному URL.
В этом примере URL-адреса /basic-admin/ и /advanced-admin/ ведут к разным версиям сайта администрирования — экземплярам AdminSite myproject.admin.basic_site и myproject.admin.advanced_site соответственно:
# urls.py
from django.urls import path
from myproject.admin import advanced_site, basic_site
urlpatterns = [
path("basic-admin/", basic_site.urls),
path("advanced-admin/", advanced_site.urls),
]
Экземпляры AdminSite принимают в конструкторе один аргумент — имя, которое может быть любым. Этот аргумент становится префиксом имен URL для обратного разрешения. Это необходимо только в том случае, если вы используете более одного AdminSite.
Добавление представлений на сайты администрирования
Как и ModelAdmin, AdminSite предоставляет метод get_urls(), который можно переопределить для определения дополнительных представлений сайта. Чтобы добавить новое представление на сайт администрирования, расширьте базовый метод get_urls(), включив в него шаблон URL для нового представления.
Примечание
Любое представление, использующее шаблоны админки или расширяющее базовый шаблон админки, должно задать request.current_app перед отображением шаблона. Ему следует присвоить значение self.name, если представление находится в AdminSite, или self.admin_site.name, если представление находится в ModelAdmin.
Добавление функции сброса пароля
Вы можете добавить функцию сброса пароля на сайт администрирования, добавив несколько строк в свой URLconf. В частности, добавьте следующие четыре шаблона:
from django.contrib import admin
from django.contrib.auth import views as auth_views
path(
"admin/password_reset/",
auth_views.PasswordResetView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="admin_password_reset",
),
path(
"admin/password_reset/done/",
auth_views.PasswordResetDoneView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="password_reset_done",
),
path(
"reset/<uidb64>/<token>/",
auth_views.PasswordResetConfirmView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="password_reset_confirm",
),
path(
"reset/done/",
auth_views.PasswordResetCompleteView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="password_reset_complete",
),
(Предполагается, что вы добавили админку по адресу admin/; URL-адреса, начинающиеся с ^admin/, необходимо разместить перед строкой, подключающей само приложение админки.)
Наличие именованного URL admin_password_reset приведет к появлению ссылки «Забыли пароль?» на стандартной странице входа в админку под полем пароля.
LogEntry объекты
-
class models.LogEntry -
Класс
LogEntryотслеживает добавление, изменение и удаление объектов через интерфейс администрирования.
LogEntry атрибуты
-
LogEntry.action_time -
Дата и время действия.
-
LogEntry.user -
Пользователь (экземпляр
AUTH_USER_MODEL), выполнивший действие.
-
LogEntry.content_type -
ContentTypeизмененного объекта.
-
LogEntry.object_id -
Текстовое представление первичного ключа измененного объекта.
-
LogEntry.object_repr -
repr()объекта после изменения.
-
LogEntry.action_flag -
Тип зарегистрированного действия:
ADDITION,CHANGE,DELETION.Например, чтобы получить список всех добавлений, выполненных через админку:
from django.contrib.admin.models import ADDITION, LogEntry LogEntry.objects.filter(action_flag=ADDITION)
-
LogEntry.change_message -
Подробное описание изменения. Например, при редактировании сообщение содержит список измененных полей. Сайт администрирования Django форматирует это содержимое как структуру JSON, чтобы
get_change_message()мог сформировать сообщение на текущем языке пользователя. Однако пользовательский код может задать это значение в виде обычной строки. Рекомендуется использовать методget_change_message()для получения этого значения вместо прямого обращения к нему.
LogEntry методы
-
LogEntry.get_edited_object()[исходный код] -
Вспомогательный метод, возвращающий связанный объект.
-
LogEntry.get_change_message()[исходный код] -
Форматирует и переводит
change_messageна текущий язык пользователя. Сообщения, созданные до Django 1.10, всегда будут отображаться на языке, на котором они были записаны.
Обратное разрешение URL-адресов административного сайта
При развёртывании AdminSite представления, предоставляемые этим сайтом, доступны с помощью системы обратного разрешения URL-адресов Django.
AdminSite предоставляет следующие именованные шаблоны URL:
Страница | Имя URL | Параметры |
|---|---|---|
Главная страница |
| |
Вход |
| |
Выход |
| |
Изменение пароля |
| |
Завершение изменения пароля |
| |
JavaScript для i18n |
| |
Главная страница приложения |
|
|
Перенаправление на страницу объекта |
|
|
Каждый экземпляр ModelAdmin предоставляет дополнительный набор именованных URL:
Страница | Имя URL | Параметры |
|---|---|---|
Список объектов |
| |
Добавление |
| |
История |
|
|
Удаление |
|
|
Изменение |
|
|
UserAdmin предоставляет именованный URL:
Страница | Имя URL | Параметры |
|---|---|---|
Изменение пароля |
|
|
Эти именованные URL зарегистрированы в пространстве имён приложения admin и в пространстве имён экземпляра, соответствующем имени экземпляра Site.
Итак, если вам нужно получить ссылку на представление изменения для определённого объекта Choice (из приложения polls) в административном интерфейсе по умолчанию, вызовите:
>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse("admin:polls_choice_change", args=(c.id,))
Будет найден первый зарегистрированный экземпляр административного приложения (независимо от имени экземпляра), а результатом станет представление для изменения экземпляров poll.Choice в этом экземпляре.
Чтобы найти URL в конкретном экземпляре административного интерфейса, передайте имя этого экземпляра в качестве подсказки current_app вызову reverse. Например, если вам нужно представление административного интерфейса именно из экземпляра с именем custom, вызовите:
>>> change_url = reverse("admin:polls_choice_change", args=(c.id,), current_app="custom")
Подробнее см. документацию о обратном разрешении URL с пространствами имён.
Для упрощения обратного разрешения URL административного интерфейса в шаблонах Django предоставляет фильтр admin_urlname, который принимает действие в качестве аргумента:
{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>
Действие в приведённых выше примерах соответствует последней части имён URL экземпляров ModelAdmin, описанных выше. Переменная opts может быть любым объектом с атрибутами app_label и model_name; обычно её предоставляет представление административного интерфейса для текущей модели.
Декоратор display
-
display(*, boolean=None, ordering=None, description=None, empty_value=None)[исходный код] -
Этот декоратор можно использовать для задания определённых атрибутов пользовательских функций отображения, применяемых с
list_displayилиreadonly_fields:@admin.display( boolean=True, ordering="-publish_date", description="Is Published?", ) def is_published(self, obj): return obj.publish_date is not NoneЭто эквивалентно непосредственному заданию некоторых атрибутов (с исходными, более длинными именами) функции:
def is_published(self, obj): return obj.publish_date is not None is_published.boolean = True is_published.admin_order_field = "-publish_date" is_published.short_description = "Is Published?"Также обратите внимание, что параметр декоратора
empty_valueсоответствует атрибутуempty_value_display, присваиваемому непосредственно функции. Его нельзя использовать вместе сboolean— эти параметры взаимоисключающие.Этот декоратор необязательно использовать для создания функции отображения, но его можно использовать без аргументов как маркер в исходном коде, чтобы обозначить назначение функции:
@admin.display def published_year(self, obj): return obj.publish_date.yearВ этом случае он не добавит к функции никаких атрибутов.
Декоратор staff_member_required
-
staff_member_required(redirect_field_name='next', login_url='admin:login')[исходный код] -
Этот декоратор используется для представлений административного интерфейса, требующих авторизации. Представление, декорированное этой функцией, будет вести себя следующим образом:
- Если пользователь вошёл в систему, является сотрудником (
User.is_staff=True) и активен (User.is_active=True), представление выполняется обычным образом. - В противном случае запрос будет перенаправлен на URL, указанный параметром
login_url, а исходный запрошенный путь будет передан в переменной строки запроса, заданной параметромredirect_field_name. Например:/admin/login/?next=/admin/polls/question/3/.
Пример использования:
from django.contrib.admin.views.decorators import staff_member_required @staff_member_required def my_view(request): ...
- Если пользователь вошёл в систему, является сотрудником (
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/contrib/admin/index/