Система администрирования 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.auth.middleware.AuthenticationMiddlewareиdjango.contrib.messages.middleware.MessageMiddlewareдолжны быть включены. - Подключите URL-адреса админки к вашему URLconf.
После выполнения этих шагов вы сможете использовать сайт администрирования, перейдя по URL-адресу, к которому вы его подключили (/admin/, по умолчанию).
Если вам нужно создать пользователя для входа, используйте команду createsuperuser. По умолчанию для входа в админку требуется, чтобы у пользователя было значение атрибута is_staff равным True.
Наконец, определите, модели каких приложений должны быть редактируемы в интерфейсе администрирования. Для каждой такой модели зарегистрируйте её в админке, как описано в ModelAdmin.
Другие темы
- Действия в админке
ModelAdminФильтры списков- Генератор документации Django admin
- Настройка JavaScript в админке
См. также
Для получения информации об обслуживании статических файлов (изображения, JavaScript и CSS), связанных с админкой в производственной среде, см. Обслуживание файлов.
Возникли проблемы? Обратитесь к FAQ: Админка.
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по умолчанию для админки. Он вызываетautodiscover()при запуске Django.
-
class apps.SimpleAdminConfig -
Этот класс работает как
AdminConfig, за исключением того, что он не вызываетautodiscover().-
default_site -
Путь импорта к классу сайта администрирования по умолчанию или вызываемому объекту, который возвращает экземпляр сайта. По умолчанию
'django.contrib.admin.sites.AdminSite'. См. Переопределение сайта администрирования по умолчанию для использования.
-
-
autodiscover() -
Эта функция пытается импортировать модуль
adminв каждом установленным приложении. Такие модули ожидают регистрации моделей в админке.Как правило, вам не нужно вызывать эту функцию напрямую, так как
AdminConfigвызывает её при запуске Django.
Если вы используете пользовательский AdminSite, обычно импортируются все подклассы ModelAdmin в ваш код и регистрируются в пользовательском AdminSite. В этом случае, чтобы отключить автоматическое обнаружение, вы должны поместить 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin' в ваше значение 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')Примечание
Эта опция
fieldsне следует путать с ключом словаряfields, который находится внутри опцииfieldsets, как описано в следующей секции.Если ни опция
fieldsниfieldsetsне присутствуют, Django по умолчанию будет отображать каждое поле, которое не являетсяAutoFieldи имеетeditable=True, в одной группе полей в том же порядке, что и в определении модели.
-
ModelAdmin.fieldsets -
Установите
fieldsetsдля управления макетом страниц администрирования «добавить» и «изменить».fieldsetsпредставляет собой список пар кортежей, в котором каждая пара кортежей представляет собой<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, которые необходимо применить к группе полей.
Пример:
{ 'classes': ('wide', 'extrapretty'), }Два полезных класса, определённых в стиле по умолчанию для администрирования, —
collapseиwide. Группы полей со стилемcollapseбудут изначально свёрнуты в администрировании и заменены небольшой ссылкой «щелкните, чтобы развернуть». Группы полей со стилемwideбудут иметь дополнительное горизонтальное пространство.
-
-
-
description -
Строка дополнительных текстов, которые можно отобразить вверху каждой группы полей, под заголовком группы. Эта строка не рендерится для
TabularInlineиз-за его макета.Обратите внимание, что это значение не экранируется с помощью HTML, когда отображается в интерфейсе администрирования. Это позволяет включить HTML, если вам это нужно. В противном случае, вы можете использовать обычный текст и
django.utils.html.escape()для экранирования HTML-специальных символов.
-
-
-
ModelAdmin.filter_horizontal -
По умолчанию,
ManyToManyFieldотображается в админ-панели с<select multiple>. Однако многовыборные поля трудно использовать при выборе многих элементов. ДобавлениеManyToManyFieldв этот список вместо этого будет использовать удобный незаметный интерфейс JavaScript «фильтр», который позволяет искать среди вариантов. Невыбранные и выбранные варианты отображаются в двух соседних полях. См.filter_vertical, чтобы использовать вертикальный интерфейс.
-
ModelAdmin.filter_vertical -
То же самое, что и
filter_horizontal, но использует вертикальное отображение интерфейса фильтра с полем невыбранных вариантов, расположенным над полем выбранных вариантов.
-
ModelAdmin.form -
По умолчанию для вашей модели динамически создается
ModelForm. Она используется для создания формы, представленной на страницах добавления/изменения. Вы можете легко предоставить свою собственнуюModelFormдля переопределения любого поведения формы по умолчанию на страницах добавления/изменения. В качестве альтернативы вы можете настроить форму по умолчанию, а не указывать совершенно новую, используя методModelAdmin.get_form().Пример см. в разделе Добавление пользовательской валидации в админ-панель.
Примечание
Если вы определили атрибут
Meta.modelдляModelForm, вы также должны определить атрибутMeta.fields(или атрибутMeta.exclude). Однако, так как у админ-панели есть свой способ определения полей, атрибутMeta.fieldsбудет игнорироваться.Если атрибут
ModelFormбудет использоваться только для админ-панели, самым простым решением является опустить атрибутMeta.model, так какModelAdminпредоставит правильную модель для использования. В качестве альтернативы вы можете установитьfields = []в классеMetaдля удовлетворения требований валидации наModelForm.Примечание
Если ваши
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В приведенном выше примере поле «возраст» будет исключено, но поле «имя» будет включено в сгенерированную форму.
-
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') -
Вызываемый объект, принимающий один аргумент — экземпляр модели. Например:
@admin.display(description='Name') def upper_case_name(obj): return ("%s %s" % (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 ("%s %s" % (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): return '%d’s' % (self.birthday.year // 10 * 10) 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')
Аргумент
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', ) 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' full_name = property(my_property) - Имена полей в
list_displayтакже появятся в качестве CSS-классов в выводе HTML в форме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. Пустой кортеж предотвратит вызовselect_relatedDjango вообще. Любой другой кортеж будет передан напрямую вselect_relatedв качестве параметров. Например:class ArticleAdmin(admin.ModelAdmin): list_select_related = ('author', 'category')вызовет
select_related('author', 'category').Если вам нужно указать динамическое значение, основанное на запросе, вы можете реализовать метод
get_list_select_related().Примечание
ModelAdminигнорирует этот атрибут, когдаselect_related()уже был вызван наQuerySetchangelist.
-
ModelAdmin.ordering -
Установите
orderingдля указания порядка сортировки списков объектов в представлениях Django admin. Это должен быть список или кортеж в том же формате, что и параметрorderingмодели.Если это не указано, Django admin будет использовать порядок сортировки по умолчанию модели.
Если вам нужен динамический порядок (например, зависящий от пользователя или языка), вы можете реализовать метод
get_ordering().Учет производительности при сортировке и упорядочивании
Для обеспечения детерминированного порядка результатов changelist добавляет
pkк сортировке, если не может найти единственный или уникальный вместе набор полей, которые обеспечивают полную сортировку.Например, если порядок по умолчанию задан по полю
name, которое не является уникальным, то changelist сортируется поnameиpk. Это может быть неэффективным, если у вас много строк и отсутствует индекс поnameиpk.
-
ModelAdmin.paginator -
Класс paginator, используемый для постраничного отображения. По умолчанию используется
django.core.paginator.Paginator. Если у класса пользовательского paginator нет такого же интерфейса конструктора, как уdjango.core.paginator.Paginator, вам также потребуется реализоватьModelAdmin.get_paginator().
-
ModelAdmin.prepopulated_fields -
Установите
prepopulated_fieldsв словарь, сопоставляющий имена полей с полями, из которых они должны заполняться:class ArticleAdmin(admin.ModelAdmin): prepopulated_fields = {"slug": ("title",)}При установке заданные поля будут использовать немного JavaScript для заполнения из назначенных полей. Основное использование этой функциональности — автоматическое формирование значения для
SlugFieldполей из одного или нескольких других полей. Сгенерированное значение формируется путем конкатенации значений исходных полей, а затем преобразования этого результата в допустимый slug (например, замена пробелов дефисами и приведение букв ASCII к нижнему регистру).Предварительно заполненные поля не изменяются JavaScript после сохранения значения. Обычно нежелательно, чтобы slugs изменялись (что приведет к изменению URL объекта, если slug используется в нем).
prepopulated_fieldsне принимаетDateTimeField,ForeignKey,OneToOneField, иManyToManyFieldполей.
-
ModelAdmin.preserve_filters -
По умолчанию примененные фильтры сохраняются на странице списка после создания, изменения или удаления объекта. Вы можете очистить фильтры, установив этот атрибут в
False.
-
ModelAdmin.radio_fields -
По умолчанию Django admin использует интерфейс select-box (<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-box (
<select>) для этих полей. Иногда вы не хотите нести затраты на выбор всех связанных экземпляров для отображения в раскрывающемся списке.Ввод Select2 выглядит аналогично стандартному вводу, но имеет функцию поиска, которая загружает варианты асинхронно. Это быстрее и удобнее для пользователя, если связанная модель имеет много экземпляров.
Вы должны определить
search_fieldsна связанном объектеModelAdmin, так как поиск автозаполнения использует его.Чтобы предотвратить несанкционированную утечку данных, пользователи должны иметь разрешение
viewилиchangeна связанный объект, чтобы использовать автозаполнение.Порядок и постраничность результатов контролируются связанными
ModelAdminметодамиget_ordering()иget_paginator().В следующем примере
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на очень больших таблицах, так как дефолтный paginator всегда выполняет запросcount(). Например, вы можете переопределить стандартную реализацию свойстваPaginator.count.
-
ModelAdmin.raw_id_fields -
По умолчанию Django admin использует интерфейс select-box (<select>) для полей, являющихся
ForeignKey. Иногда вы не хотите нести затраты на выбор всех связанных экземпляров для отображения в раскрывающемся списке.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, «Сохранить и добавить другой» будет заменено кнопкой «Сохранить как новый», которая создаст новый объект (с новым ID) вместо обновления существующего объекта.По умолчанию
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 поиска “follow”:search_fields = ['foreign_key__related_fieldname']
Например, если у вас есть запись блога с автором, следующее определение позволит искать записи блога по адресу электронной почты автора:
search_fields = ['user__email']
Когда пользователь выполняет поиск в поле поиска администратора, Django разбивает запрос на слова и возвращает все объекты, содержащие каждое слово, не учитывая регистр (используя
icontainsпоиск), где каждое слово должно присутствовать хотя бы в одном изsearch_fields. Например, еслиsearch_fieldsустановлено в['first_name', 'last_name']и пользователь ищетjohn lennon, Django выполнит запрос, эквивалентный следующему SQLWHEREусловию: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 выполнит запрос, эквивалентный следующему SQLWHEREусловию:WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')
Если вы не хотите использовать
icontainsв качестве поиска, вы можете использовать любой поиск, добавив его к полю. Например, вы можете использоватьexact, установивsearch_fieldsв['first_name__exact'].Также доступны некоторые (старые) сокращения для указания поиска по полю. Вы можете префиксровать поле в
search_fieldsследующим символом, и это эквивалентно добавлению__<lookup>к полю:Префикс Поиск ^ startswith= iexact@ searchNone icontainsЕсли вам нужно настроить поиск, вы можете использовать
ModelAdmin.get_search_results()для предоставления дополнительных или альтернативных функций поиска.Изменено в Django 4.1:Поиск с использованием нескольких поисковых терминов теперь применяется в одном вызове
filter(), а не в последовательныхfilter()вызовах.Для многозначных отношений это означает, что строки из связанной модели должны соответствовать всем терминам, а не любому термину. Например, если
search_fieldsустановлено в['child__name', 'child__age']и пользователь ищет'Jamal 17', строки родительских объектов будут возвращаться только в том случае, если существует отношение к некоторому 17-летнему ребенку по имени Джамаль, а не также возвращаться родителям, у которых есть только младший или старший ребенок по имени Джамаль, помимо других 17-летних.См. раздел Spanning multi-valued relationships для более подробного обсуждения этого различия.
-
ModelAdmin.search_help_text -
New in Django 4.0.
Установите
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 -
По умолчанию страница списка изменений позволяет сортировать по всем полям модели (и вызовам, которые используют
orderingаргумент декоратораdisplay()или имеютadmin_order_fieldатрибут) указанные вlist_display.Если вы хотите отключить сортировку для некоторых столбцов, установите
sortable_byв коллекцию (например,list,tuple, илиset), подмножествоlist_display, которое вы хотите отсортировать. Пустая коллекция отключает сортировку для всех столбцов.Если вам нужно динамически указать этот список, реализуйте метод
get_sortable_by()вместо этого.
-
ModelAdmin.view_on_site -
Установите
view_on_siteдля управления отображением ссылки «Просмотреть на сайте». Эта ссылка должна перенаправлять вас на URL, где можно отобразить сохранённый объект.Это значение может быть либо логическим флагом, либо вызываемым объектом. Если
True(по умолчанию), будет использован метод объектаget_absolute_url()для генерации 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
Custom template options
Раздел Переопределение шаблонов административной панели описывает, как переопределить или расширить стандартные шаблоны административной панели. Используйте следующие параметры для переопределения стандартных шаблонов, используемых представлениями 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.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изменяет список отображаемых объектов на те, которые соответствуют предоставленному поисковому запросу. Он принимает запрос, набор результатов, применяющий текущие фильтры, и введенный пользователем поисковый запрос. Он возвращает кортеж, содержащий измененный набор результатов для реализации поиска и булево значение, указывающее, могут ли результаты содержать дубликаты.По умолчанию поиск выполняется по полям, указанным в
ModelAdmin.search_fields.Этот метод можно переопределить, чтобы реализовать собственный метод поиска. Например, вы можете выполнить поиск по целочисленному полю или использовать внешний инструмент, такой как Solr или Haystack. Вы должны определить, могут ли изменения набора результатов, реализованные вашим методом поиска, ввести дубликаты в результаты и вернуть
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.Изменено в Django 4.1:Поиск по нескольким поисковым терминам теперь применяется в одном вызове
filter(), а не в последовательных вызовахfilter().Для многозначных отношений это означает, что строки из связанной модели должны соответствовать всем терминам, а не любому термину. Например, если
search_fieldsустановлено на['child__name', 'child__age'], и пользователь ищет'Jamal 17', родительские строки будут возвращены только в том случае, если существует отношение к какому-то 17-летнему ребенку по имени Джамаль, а не возвращать также родителей, у которых просто есть младший или старший ребенок по имени Джамаль, кроме какого-то другого 17-летнего ребенка.См. раздел Связывание многозначных отношений для более подробного обсуждения этого различия.
-
Метод
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в форме добавления) и ожидается, что он вернёт список пар кортежей, где каждая пара кортежей представляет собой<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, иначе при добавлении связанных объектов может возникнуть ошибка «Неверный запрос».
-
ModelAdmin.get_inlines(request, obj) -
Метод
get_inlinesполучаетHttpRequestиobjредактируемого объекта (илиNoneв форме добавления) и ожидается, что он вернёт итерируемый объект встраиваемых объектов. Вы можете переопределить этот метод, чтобы динамически добавлять встраиваемые объекты на основе запроса или экземпляра модели вместо указания их вModelAdmin.inlines.
-
ModelAdmin.get_urls() -
Метод
get_urlsна объектеModelAdminвозвращает URL-адреса, которые будут использоваться для данного ModelAdmin аналогично URLconf. Поэтому вы можете их расширять, как описано в диспетчере URL: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.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 %}Примечание
Обратите внимание, что пользовательские шаблоны включены перед стандартными URL-адресами администрирования: шаблоны URL-адресов администрирования очень общие и будут соответствовать почти всему, поэтому, как правило, вы захотите поместить свои пользовательские URL-адреса перед встроенными.
В этом примере,
my_viewбудет доступен по адресу/admin/myapp/mymodel/my_view/(предполагается, что URL-адреса администрирования включены в/admin/.)Однако, функция
self.my_viewзарегистрированная выше, имеет две проблемы:- Она не выполняет проверки разрешений, поэтому она будет доступна всем пользователям.
- Она не предоставляет никаких заголовков, чтобы предотвратить кэширование. Это означает, что если страница извлекает данные из базы данных, а кэширование включено, страница может отображать устаревшую информацию.
Поскольку это обычно не то, что вы хотите, Django предоставляет удобную оболочку для проверки разрешений и маркировки представления как некэшируемого. Эта оболочка -
AdminSite.admin_view()(то естьself.admin_site.admin_viewвнутри экземпляраModelAdmin); используйте её так: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Обратите внимание на обернутое представление в пятой строке выше:
path('my_view/', self.admin_site.admin_view(self.my_view))Это обертывание защитит
self.my_viewот несанкционированного доступа и применит декораторdjango.views.decorators.cache.never_cache(), чтобы убедиться, что он не будет кэширован, если включено кэширование.Если страница кэшируемая, но вы всё равно хотите, чтобы проверка разрешений выполнялась, вы можете передать аргумент
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) для использования в админских представлениях добавления и изменения.Например, если вы хотите отобразить определённый inline только в представлении изменения, вы можете переопределить
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позволяет переопределить стандартное поле формы для поля foreign key. Например, чтобы вернуть подмножество объектов для этого поля foreign key, основанное на пользователе: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для фильтрации поля foreign keyCarтак, чтобы отображались только автомобили, принадлежащие экземпляру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может быть переопределён для изменения стандартного поля формы для поля many-to-many. Например, если владелец может владеть несколькими машинами, а машины могут принадлежать нескольким владельцам (отношение many-to-many) — вы можете отфильтровать поле foreign keyCarдля отображения только автомобилей, принадлежащих экземпляру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'] += (('ready', 'Ready for deployment'),) return super().formfield_for_choice_field(db_field, request, **kwargs)Примечание
Любой атрибут
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Примечание
Если вы определены атрибут
Meta.modelнаModelForm, вы также должны определить атрибутMeta.fields(или атрибутMeta.exclude). ОднакоModelAdminигнорирует это значение, переопределяя его атрибутомModelAdmin.list_editable. Проще всего опустить атрибутMeta.model, так какModelAdminпредоставит правильную модель для использования.
-
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) -
Объекты на странице списка изменений могут быть отфильтрованы с помощью запросов из строки запроса 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, если пользователь имеет права «изменить» или «просмотреть».
-
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бэкэнд. См. пример custom 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) -
Новое в Django 4.0.
Метод для настройки ключевых аргументов, передаваемых в конструктор formset. Например, для передачи
requestформам formset: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для форм formset.
-
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.Этот метод должен возвращать 4-кортеж
(deleted_objects, model_count, perms_needed, protected).deleted_objects— список строк, представляющих все объекты, которые будут удалены. Если есть какие-либо связанные объекты, подлежащие удалению, список является вложенным и включает эти связанные объекты. Список отформатирован в шаблоне с использованием фильтраunordered_list.model_count— словарь, сопоставляющий множественное число verbose_name каждого модели к количеству объектов, которые будут удалены.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 для страницы истории изменений заданного экземпляра модели.
Изменено в Django 4.1:Добавлена пагинация.
В отличие от методов типа 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
Django admin JavaScript использует библиотеку jQuery.
Чтобы избежать конфликтов с пользовательскими скриптами или библиотеками, jQuery Django (версия 3.6.0) имеет пространство имён django.jQuery. Если вы хотите использовать jQuery в собственном admin JavaScript без включения второй копии, вы можете использовать объект django.jQuery в списках изменений и представлениях добавления/редактирования. Кроме того, ваши собственные admin-формы или виджеты, зависящие от django.jQuery должны указывать js=['admin/js/jquery.init.js', …] при определении активов форм.
jQuery был обновлён с версии 3.5.1 до 3.6.0.
Класс 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 для предотвращения ошибок. См. документацию форм по пользовательской валидации и, более конкретно, примечания по валидации форм моделей для получения дополнительной информации.
InlineModelAdmin объекты
-
class InlineModelAdmin
-
class TabularInline
-
class StackedInline -
В административном интерфейсе есть возможность редактировать модели на той же странице, что и родительская модель. Это называются строками. Предположим, у вас есть эти две модели:
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 class BookInline(admin.TabularInline): model = Book class AuthorAdmin(admin.ModelAdmin): inlines = [ BookInline, ]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 админ использует интерфейс выпадающего списка (<select>) для полей, которые
ForeignKey. Иногда вам не нужно учитывать накладные расходы, связанные с выбором всех связанных экземпляров для отображения в выпадающем списке.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'.Изменено в Django 4.0:Была добавлена поддержка возврата к
InlineModelAdmin.verbose_name.
-
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 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, вам необходимо явно определить внешний ключ, так как автоматически это сделать невозможно:
from django.contrib import admin
from myapp.models import Friendship
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
Работа с моделями многие-ко-многим
По умолчанию виджеты администрирования для взаимосвязей «многие ко многим» будут отображаться в той модели, которая содержит фактическую ссылку на 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
class MembershipInline(admin.TabularInline):
model = Group.members.through
class PersonAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
class GroupAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
exclude = ('members',)
В этом примере стоит отметить две особенности.
Во-первых, класс 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)
Первый шаг для отображения этой промежуточной модели в администрировании — определить встроенный класс для модели 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.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 для получения более подробной информации.
Переопределение шаблонов администрирования
Вы можете переопределить многие шаблоны, которые модуль администрирования использует для генерации различных страниц сайта администрирования. Вы даже можете переопределить некоторые из этих шаблонов для конкретного приложения или конкретной модели.
Настройка каталогов шаблонов администрирования проекта
Файлы шаблонов администрирования расположены в каталоге 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/ нашего проекта и внесли необходимые изменения.
Если мы хотели добавить инструмент в представление списка изменений только для определенной модели с именем «Страница», мы бы скопировали тот же файл в каталог 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>
: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 %}.
Переменные тёмной темы были перемещены в отдельный файл стилей и блок шаблона.
AdminSite объекты
-
class AdminSite(name='admin') -
Сайт администратора Django представлен экземпляром
django.contrib.admin.sites.AdminSite; по умолчанию, создается экземпляр этого класса какdjango.contrib.admin.site, и вы можете зарегистрировать ваши модели и экземплярыModelAdminс ним.Если вы хотите настроить сайт администратора по умолчанию, вы можете переопределить его.
При создании экземпляра
AdminSite, вы можете указать уникальное имя экземпляра, используя аргументnameконструктора. Это имя экземпляра используется для идентификации экземпляра, особенно при обращении к URL-адресам администратора. Если имя экземпляра не указано, используется имя по умолчаниюadmin. См. Настройка класса AdminSite для примера настройки классаAdminSite.
AdminSite атрибуты
Шаблоны могут переопределять или расширять базовые шаблоны администратора, как описано в Переопределении шаблонов администратора.
-
AdminSite.site_header -
Текст, отображаемый вверху каждой страницы администратора, как
<h1>(строка). По умолчанию это “Django administration”.
-
AdminSite.site_title -
Текст, отображаемый внизу каждой страницы администратора, как
<title>(строка). По умолчанию это “Django site admin”.
-
AdminSite.site_url -
URL-адрес ссылки «Просмотреть сайт» вверху каждой страницы администратора. По умолчанию,
site_urlэто/. Установите его вNoneдля удаления ссылки.Для сайтов, работающих на подпути, метод
each_context()проверяет, установлен лиrequest.META['SCRIPT_NAME']в текущем запросе, и использует это значение, еслиsite_urlне установлено на значение, отличное от/.
-
AdminSite.index_title -
Текст, отображаемый вверху страницы индекса администратора (строка). По умолчанию это “Site administration”.
-
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_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-адрес администратора для добавления новой модели
-
Изменено в Django 4.0:Была добавлена переменная
modelдля каждой модели. -
-
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: отслеживаниеdictadd,change,delete, иviewразрешений -
admin_url: URL-адрес списка изменений админки для модели -
add_url: URL-адрес админки для добавления новой записи модели
Списки приложений и моделей отсортированы по именам в алфавитном порядке. Вы можете переопределить этот метод, чтобы изменить порядок по умолчанию на странице индекса админки.
Изменено в Django 4.1:Был добавлен аргумент
app_label. -
-
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.sites.AlreadyRegisteredесли модель уже зарегистрирована.
-
AdminSite.unregister(model_or_iterable) -
Удаляет регистрацию указанного класса модели (или итерируемого списка классов).
Возбуждает
django.contrib.admin.sites.NotRegisteredесли модель не зарегистрирована.
Подключение экземпляров AdminSite в ваш URLconf
Последний шаг настройки Django админки — подключить ваш экземпляр AdminSite в ваш URLconf. Сделайте это, указав URL для метода AdminSite.urls. Необязательно использовать include().
В этом примере мы регистрируем стандартный экземпляр AdminSite django.contrib.admin.site по адресу /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. Это означает, что нужно указать 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin' в настройке INSTALLED_APPS.
Переопределение стандартного сайта админки
Вы можете переопределить стандартный 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() и включите шаблон для вашего нового представления.
Примечание
Любое представление, которое использует шаблоны админки или расширяет базовый шаблон админки, должно задать request.current_app перед рендерингом шаблона. Оно должно быть установлено либо в self.name, если ваше представление находится на странице AdminSite, либо в self.admin_site.name если ваше представление находится на странице ModelAdmin.
Добавление функции сброса пароля
Вы можете добавить функцию сброса пароля в сайт админки, добавив несколько строк в ваш URLconf. Конкретно, добавьте эти четыре шаблона:
from django.contrib.auth import views as auth_views
path(
'admin/password_reset/',
auth_views.PasswordResetView.as_view(),
name='admin_password_reset',
),
path(
'admin/password_reset/done/',
auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done',
),
path(
'reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm',
),
path(
'reset/done/',
auth_views.PasswordResetCompleteView.as_view(),
name='password_reset_complete',
),
(Предполагается, что вы добавили админку по адресу admin/ и необходимо расположить URL, начинающиеся с ^admin/ перед строкой, включающей сам модуль админки).
Наличие admin_password_reset URL вызовет появление ссылки «забыли пароль?» на стандартной странице входа в админку под полем пароля.
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 Admin форматирует это содержимое как 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 | Параметры |
|---|---|---|
| Главная | index | |
| Вход | login | |
| Выход | logout | |
| Смена пароля | password_change | |
| Смена пароля выполнена | password_change_done | |
| JavaScript для i18n | jsi18n | |
| Главная страница приложения | app_list | app_label |
| Перенаправление на страницу объекта | view_on_site |
content_type_id, object_id
|
Каждый экземпляр ModelAdmin предоставляет дополнительный набор именованных URL-адресов:
| Страница | Имя URL | Параметры |
|---|---|---|
| Список изменений | {{ app_label }}_{{ model_name }}_changelist | |
| Добавить | {{ app_label }}_{{ model_name }}_add | |
| История | {{ app_label }}_{{ model_name }}_history | object_id |
| Удалить | {{ app_label }}_{{ model_name }}_delete | object_id |
| Изменить | {{ app_label }}_{{ model_name }}_change | object_id |
UserAdmin предоставляет именованный URL:
| Страница | Имя URL | Параметры |
|---|---|---|
| Смена пароля | auth_user_password_change | user_id |
Эти именованные URL регистрируются в пространстве имён приложения admin, а также в пространстве имён экземпляра, соответствующем имени экземпляра Site.
Итак, если вам нужно получить ссылку на представление Change для конкретного объекта Choice (из приложения polls) в стандартной админке, вы вызовите:
>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,))
Это найдёт первый зарегистрированный экземпляр приложения админки (какое угодно имя экземпляра) и обратится к представлению для изменения объектов poll.Choice в этом экземпляре.
Если вам нужно найти URL в определённом экземпляре админки, укажите имя этого экземпляра в качестве подсказки для обратного вызова. Например, если вам нужен административный вид из экземпляра админки под названием 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/4.1/ref/contrib/admin/index/