Сайт администрирования 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 администрирования
- Настройка JavaScript в администрировании
См. также
Для получения информации о предоставлении статических файлов (изображений, JavaScript и CSS), связанных с администрированием, в рабочей среде, см. Предоставление файлов.
Возникли проблемы? Попробуйте Вопросы и ответы: администрирование.
ModelAdmin объекты
-
class ModelAdmin -
Класс
ModelAdminпредставляет модель в интерфейсе администрирования. Обычно они хранятся в файле с именемadmin.pyв вашем приложении. Давайте рассмотрим примерModelAdmin:from django.contrib import admin from myapp.models import Author class AuthorAdmin(admin.ModelAdmin): pass admin.site.register(Author, AuthorAdmin)Нужен ли вообще объект
ModelAdmin?В приведенном примере класс
ModelAdminне определяет никаких пользовательских значений (еще). В результате будет предоставлен интерфейс администрирования по умолчанию. Если вы довольны интерфейсом администрирования по умолчанию, вам вообще не нужно определять объектModelAdmin— вы можете зарегистрировать класс модели без предоставления описанияModelAdmin. Приведенный пример можно упростить до:from django.contrib import admin from myapp.models import Author admin.site.register(Author)
Декоратор register
-
register(*models, site=django.contrib.admin.sites.site) -
Также есть декоратор для регистрации ваших классов
ModelAdmin:from django.contrib import admin from .models import Author @admin.register(Author) class AuthorAdmin(admin.ModelAdmin): passОн принимает один или несколько классов моделей для регистрации в
ModelAdmin. Если вы используете пользовательскийAdminSite, передайте его с помощью ключевого аргументаsite:from django.contrib import admin from .models import Author, Editor, Reader from myproject.admin_site import custom_admin_site @admin.register(Author, Reader, Editor, site=custom_admin_site) class PersonAdmin(admin.ModelAdmin): passВы не можете использовать этот декоратор, если вам необходимо сослаться на ваш класс модели администрирования в его методе
__init__(), напримерsuper(PersonAdmin, self).__init__(*args, **kwargs). Вы можете использоватьsuper().__init__(*args, **kwargs).
Обнаружение файлов администрирования
Когда вы помещаете 'django.contrib.admin' в настройку INSTALLED_APPS, Django автоматически ищет модуль admin в каждом приложении и импортирует его.
-
class apps.AdminConfig -
Это класс
AppConfigпо умолчанию для администрирования. Он вызывает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>на странице формы администрирования. (Набор<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 f"{obj.first_name} {obj.last_name}".upper() class PersonAdmin(admin.ModelAdmin): list_display = [upper_case_name] -
Строка, представляющая метод
ModelAdmin, принимающий один аргумент — экземпляр модели. Например:class PersonAdmin(admin.ModelAdmin): list_display = ["upper_case_name"] @admin.display(description="Name") def upper_case_name(self, obj): return f"{obj.first_name} {obj.last_name}".upper() -
Строка, представляющая атрибут или метод модели (без каких-либо обязательных аргументов). Например:
from django.contrib import admin from django.db import models class Person(models.Model): name = models.CharField(max_length=50) birthday = models.DateField() @admin.display(description="Birth decade") def decade_born_in(self): decade = self.birthday.year // 10 * 10 return f"{decade}’s" class PersonAdmin(admin.ModelAdmin): list_display = ["name", "decade_born_in"]
Несколько особых случаев, касающихся
list_display:- Если поле является
ForeignKey, Django отобразит__str__()связанного объекта. -
ManyToManyFieldполя не поддерживаются, так как это потребовало бы выполнения отдельного SQL запроса для каждой строки в таблице. Если вам все же нужно это сделать, добавьте в свою модель пользовательский метод и укажите имя этого метода вlist_display. (См. ниже больше информации о пользовательских методах вlist_display.) - Если поле является
BooleanField, Django отобразит красивую иконку «да», «нет» или «неизвестно» вместоTrue,False, илиNone. -
Если заданная строка является методом модели,
ModelAdminили вызываемым объектом, Django по умолчанию будет HTML-экранировать вывод. Чтобы экранировать пользовательский ввод и разрешить свои собственные неэкранированные теги, используйтеformat_html().Вот полный пример модели:
from django.contrib import admin from django.db import models from django.utils.html import format_html class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) @admin.display def colored_name(self): return format_html( '<span style="color: #{};">{} {}</span>', self.color_code, self.first_name, self.last_name, ) class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "last_name", "colored_name"] - Как некоторые примеры уже показали, при использовании вызываемого объекта, метода модели или метода
ModelAdmin, вы можете настроить заголовок столбца, обернув вызываемый объект декораторомdisplay()и передав аргументdescription. -
Если значение поля
None, пустая строка или итерируемый объект без элементов, Django отобразит-(тире). Вы можете переопределить это с помощьюAdminSite.empty_value_display:from django.contrib import admin admin.site.empty_value_display = "(None)"
Вы также можете использовать
ModelAdmin.empty_value_display:class PersonAdmin(admin.ModelAdmin): empty_value_display = "unknown"Или на уровне поля:
class PersonAdmin(admin.ModelAdmin): list_display = ["name", "birth_date_view"] @admin.display(empty_value="unknown") def birth_date_view(self, obj): return obj.birth_date -
Если заданная строка является методом модели,
ModelAdminили вызываемым объектом, возвращающимTrue,False, илиNone, Django отобразит красивую иконку «да», «нет» или «неизвестно», если вы обернёте метод декораторомdisplay(), передав аргументbooleanсо значениемTrue:from django.contrib import admin from django.db import models class Person(models.Model): first_name = models.CharField(max_length=50) birthday = models.DateField() @admin.display(boolean=True) def born_in_fifties(self): return 1950 <= self.birthday.year < 1960 class PersonAdmin(admin.ModelAdmin): list_display = ["name", "born_in_fifties"] -
Метод
__str__()так же допустим вlist_displayкак и любой другой метод модели, поэтому сделать это совершенно нормально:list_display = ["__str__", "some_other_field"]
-
Обычно элементы
list_displayкоторые не являются фактическими полями базы данных, не могут использоваться для сортировки (потому что Django выполняет всю сортировку на уровне базы данных).Однако, если элемент
list_displayпредставляет определенное поле базы данных, вы можете указать это, используя декораторdisplay()на методе, передав аргументordering:from django.contrib import admin from django.db import models from django.utils.html import format_html class Person(models.Model): first_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) @admin.display(ordering="first_name") def colored_first_name(self): return format_html( '<span style="color: #{};">{}</span>', self.color_code, self.first_name, ) class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "colored_first_name"]Это расскажет Django, что при сортировке по
colored_first_nameв администрировании необходимо сортировать по полюfirst_name.Для указания сортировки по убыванию с аргументом
orderingможно использовать префикс дефиса для имени поля. Используя приведенный выше пример, это будет выглядеть так:@admin.display(ordering="-first_name") def colored_first_name(self): ...Аргумент
orderingподдерживает поиск по запросам для сортировки по значениям связанных моделей. Этот пример включает колонку «Имя автора» в списке отображения и позволяет сортировать ее по имени:class Blog(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey(Person, on_delete=models.CASCADE) class BlogAdmin(admin.ModelAdmin): list_display = ["title", "author", "author_first_name"] @admin.display(ordering="author__first_name") def author_first_name(self, obj): return obj.author.first_nameВыражения запроса могут использоваться с аргументом
ordering:from django.db.models import Value from django.db.models.functions import Concat class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @admin.display(ordering=Concat("first_name", Value(" "), "last_name")) def full_name(self): return self.first_name + " " + self.last_name -
Элементы
list_displayтакже могут быть свойствамиclass Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @property @admin.display( ordering="last_name", description="Full name of the person", ) 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()уже был вызван дляQuerySetсписка изменений.
-
ModelAdmin.ordering -
Установите
orderingдля задания порядка сортировки списков объектов в представлениях Django admin. Значение должно быть списком или кортежем в том же формате, что и параметрorderingмодели.Если это не задано, Django admin будет использовать порядок сортировки по умолчанию модели.
Если вам нужно указать динамический порядок (например, зависящий от пользователя или языка), вы можете реализовать метод
get_ordering().Соображения по производительности при сортировке
Для обеспечения детерминированного порядка результатов список изменений добавляет
pkк порядку сортировки, если не может найти единственное или уникальное вместе взятое множество полей, обеспечивающих полную сортировку.Например, если порядок сортировки по умолчанию основан на поле
name, которое не является уникальным, то список изменений сортируется поnameиpk. Это может плохо сказываться на производительности, если у вас много строк и нет индекса поnameиpk.
-
ModelAdmin.paginator -
Класс пагинатора, который будет использоваться для пагинации. По умолчанию используется
django.core.paginator.Paginator. Если у класса пользовательского пагинатора нет такого же интерфейса конструктора, как уdjango.core.paginator.Paginator, вам также необходимо реализоватьModelAdmin.get_paginator().
-
ModelAdmin.prepopulated_fields -
Установите
prepopulated_fieldsв словарь, сопоставляющий имена полей с полями, из которых они должны быть заполнены:class ArticleAdmin(admin.ModelAdmin): prepopulated_fields = {"slug": ["title"]}При установке указанные поля будут использовать JavaScript для заполнения из назначенных полей. Основное использование этой функции — автоматическое создание значения для
SlugFieldполей из одного или нескольких других полей. Сгенерированное значение создаётся путём конкатенации значений исходных полей, а затем преобразования результата в допустимый slug (например, заменяя пробелы дефисами и приводя ASCII-буквы к нижнему регистру).Предварительно заполненные поля не изменяются JavaScript после сохранения значения. Обычно нежелательно, чтобы slug изменялись (что привело бы к изменению URL объекта, если slug используется в нём).
prepopulated_fieldsне поддерживает поляDateTimeField,ForeignKey,OneToOneField, иManyToManyField.
-
ModelAdmin.preserve_filters -
По умолчанию, примененные фильтры сохраняются на странице списка после создания, редактирования или удаления объекта. Для очистки фильтров установите этот атрибут в
False.
-
ModelAdmin.radio_fields -
По умолчанию, админка Django использует интерфейс выбора (<select>) для полей, являющихся
ForeignKeyили имеющихchoices. Если поле есть вradio_fields, Django будет использовать интерфейс радиокнопок вместо него. Предположим, чтоgroup— этоForeignKeyв моделиPerson:class PersonAdmin(admin.ModelAdmin): radio_fields = {"group": admin.VERTICAL}У вас есть возможность использовать
HORIZONTALилиVERTICALиз модуляdjango.contrib.admin.Не включайте поле в
radio_fields, если оно не являетсяForeignKeyили не имеетchoices.
-
ModelAdmin.autocomplete_fields -
autocomplete_fields— это список полейForeignKeyи/илиManyToManyFieldполей, которые вы хотите изменить на автодополнение Select2.По умолчанию админка использует интерфейс выбора (<select>) для этих полей. Иногда вам не нужно тратить вычислительные ресурсы на выбор всех связанных экземпляров для отображения в выпадающем списке.
Ввод Select2 похож на стандартный ввод, но имеет функцию поиска, которая загружает варианты асинхронно. Это быстрее и удобнее, если связанная модель имеет много экземпляров.
Вы должны определить
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на очень больших таблицах, так как пагинатор по умолчанию всегда выполняет запросcount(). Например, вы можете переопределить стандартную реализацию свойстваPaginator.count.
-
ModelAdmin.raw_id_fields -
По умолчанию, админка Django использует интерфейс выбора (<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 -
По умолчанию админская панель отображает все поля как редактируемые. Любые поля в этом параметре (который должен быть списком или кортежем) будут отображать свои данные как есть и не будут редактируемыми; они также исключаются из
ModelForm, используемого для создания и редактирования. Обратите внимание, что при указанииModelAdmin.fieldsилиModelAdmin.fieldsetsполя только для чтения должны быть явно присутствовать, чтобы отображаться (в противном случае они игнорируются).Если
readonly_fieldsиспользуется без явного указания порядка черезModelAdmin.fieldsилиModelAdmin.fieldsets, они будут добавлены в конец после всех редактируемых полей.Поле только для чтения может не только отображать данные из поля модели, но и отображать вывод метода модели или метода самого класса
ModelAdmin. Это очень похоже на то, как ведет себяModelAdmin.list_display. Это позволяет использовать админский интерфейс для предоставления обратной связи о состоянии редактируемых объектов, например:from django.contrib import admin from django.utils.html import format_html_join from django.utils.safestring import mark_safe class PersonAdmin(admin.ModelAdmin): readonly_fields = ["address_report"] # description functions like a model field's verbose_name @admin.display(description="Address") def address_report(self, instance): # assuming get_full_address() returns a list of strings # for each line of the address and you want to separate each # line by a linebreak return format_html_join( mark_safe("<br>"), "{}", ((line,) for line in instance.get_full_address()), ) or mark_safe("<span class='errors'>I can't determine this address.</span>")
-
ModelAdmin.save_as -
Установите
save_asдля включения функции «сохранить как новый» на формах изменения админской панели.Обычно у объектов есть три варианта сохранения: «Сохранить», «Сохранить и продолжить редактирование» и «Сохранить и добавить ещё». Если
save_asимеет значениеTrue, «Сохранить и добавить ещё» будет заменено кнопкой «Сохранить как новый», которая создаст новый объект (с новым идентификатором), а не обновит существующий.По умолчанию
save_asустановлено вFalse.
-
ModelAdmin.save_as_continue -
Когда
save_as=True, по умолчанию после сохранения нового объекта происходит перенаправление на страницу изменения этого объекта. Если вы установитеsave_as_continue=False, перенаправление будет на страницу списка изменений.По умолчанию
save_as_continueустановлено вTrue.
-
ModelAdmin.save_on_top -
Установите
save_on_topдля добавления кнопок сохранения в верхней части ваших форм изменения в админской панели.Обычно кнопки сохранения появляются только внизу форм. Если вы установите
save_on_top, кнопки появятся и сверху, и снизу.По умолчанию
save_on_topустановлено вFalse.
-
ModelAdmin.search_fields -
Установите
search_fieldsдля включения поля поиска на странице списка изменений админской панели. Это поле должно быть набором имён полей, которые будут проиндексированы при запросе поиска пользователем в текстовом поле.Эти поля должны быть полями типа текста, например,
CharFieldилиTextField. Также можно выполнить связанный поиск поForeignKeyилиManyToManyFieldс помощью обозначения API поиска «follow»:search_fields = ["foreign_key__related_fieldname"]
Например, если у вас есть запись блога с автором, следующее определение позволит искать записи блога по электронному адресу автора:
search_fields = ["user__email"]
Когда пользователь выполняет поиск в поле поиска админской панели, Django разбивает запрос на слова и возвращает все объекты, содержащие каждое из слов, без учёта регистра (используя поиск
icontains), где каждое слово должно присутствовать хотя бы в одном изsearch_fields. Например, еслиsearch_fieldsустановлено в['first_name', 'last_name']и пользователь ищетjohn lennon, Django выполнит эквивалентную SQL-операторWHERE:WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%') AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
Запрос поиска может содержать выражения в кавычках с пробелами. Например, если пользователь ищет
"john winston"или'john winston', Django выполнит эквивалентную SQL-операторWHERE:WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')
Если вы не хотите использовать
icontainsв качестве поиска, вы можете использовать любой поиск, добавив его к полю. Например, вы можете использоватьexact, установивsearch_fieldsв['first_name__exact'].Также доступны некоторые (более старые) сокращения для указания поиска по полю. Вы можете добавить префикс к полю в
search_fieldsследующим символами, и это эквивалентно добавлению__<lookup>к полю:Префикс Поиск ^ startswith= iexact@ searchNone icontainsЕсли вам нужно настроить поиск, вы можете использовать
ModelAdmin.get_search_results()для предоставления дополнительных или альтернативных параметров поиска.Изменено в Django 4.1:Поиск с несколькими поисковыми терминами сейчас применяется в одном вызове
filter(), а не в последовательных вызовахfilter().Для многозначных взаимосвязей это означает, что строки из связанной модели должны соответствовать всем терминам, а не любому термину. Например, если
search_fieldsустановлено в['child__name', 'child__age']и пользователь ищет'Jamal 17', родительские строки будут возвращены только если существует связь с каким-то 17-летним ребенком по имени Джамаль, а не также возвращаются родители, у которых просто есть младший или старший ребенок по имени Джамаль, помимо какого-то другого 17-летнего.См. тему Связи с несколькими значениями для получения дополнительной информации об этом различии.
-
ModelAdmin.search_help_text -
Установите
search_help_textдля указания описательного текста для поля поиска, который будет отображаться под ним.
-
ModelAdmin.show_full_result_count -
Установите
show_full_result_countдля управления тем, следует ли отображать полное количество объектов на отфильтрованной странице администрирования (например,99 results (103 total)). Если этот параметр установлен вFalse, вместо этого отображается текст типа99 results (Show all).Значение по умолчанию
show_full_result_count=Trueгенерирует запрос для выполнения подсчёта по всей таблице, что может быть дорогостоящим, если таблица содержит большое количество строк.
-
ModelAdmin.sortable_by -
По умолчанию страница списка изменений позволяет сортировать по всем полям модели (и вызываемым функциям, которые используют
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(по умолчанию), для генерации URL будет использоваться метод объектаget_absolute_url().Если ваша модель имеет метод
get_absolute_url(), но вы не хотите, чтобы кнопка «Просмотреть на сайте» отображалась, вам нужно только установитьview_on_siteв значениеFalse:from django.contrib import admin class PersonAdmin(admin.ModelAdmin): view_on_site = FalseЕсли это вызываемая функция, она принимает экземпляр модели в качестве параметра. Например:
from django.contrib import admin from django.urls import reverse class PersonAdmin(admin.ModelAdmin): def view_on_site(self, obj): url = reverse("person-detail", kwargs={"slug": obj.slug}) return "https://example.com" + url
Настраиваемые параметры шаблона
Раздел Переопределение шаблонов админ-панели описывает, как переопределить или расширить стандартные шаблоны админ-панели. Используйте следующие параметры для переопределения стандартных шаблонов, используемых представлениями ModelAdmin:
-
ModelAdmin.add_form_template -
Путь к пользовательскому шаблону, используемому представлением
add_view().
-
ModelAdmin.change_form_template -
Путь к пользовательскому шаблону, используемому представлением
change_view().
-
ModelAdmin.change_list_template -
Путь к пользовательскому шаблону, используемому представлением
changelist_view().
-
ModelAdmin.delete_confirmation_template -
Путь к пользовательскому шаблону, используемому представлением
delete_view()для отображения страницы подтверждения при удалении одного или нескольких объектов.
-
ModelAdmin.delete_selected_confirmation_template -
Путь к пользовательскому шаблону, используемому методом действия
delete_selectedдля отображения страницы подтверждения при удалении одного или нескольких объектов. См. документацию по действиям.
-
ModelAdmin.object_history_template -
Путь к пользовательскому шаблону, используемому представлением
history_view().
-
ModelAdmin.popup_response_template -
Путь к пользовательскому шаблону, используемому представлениями
response_add(),response_change()иresponse_delete().
ModelAdmin методы
Предупреждение
При переопределении ModelAdmin.save_model() и ModelAdmin.delete_model() ваш код должен сохранять/удалять объект. Они не предназначены для вето, а позволяют выполнять дополнительные операции.
-
ModelAdmin.save_model(request, obj, form, change) -
Метод
save_modelполучаетHttpRequest, экземпляр модели, экземплярModelForm, и булево значение, определяющее, добавляется или изменяется объект. Переопределение этого метода позволяет выполнять операции до или после сохранения. Вызовитеsuper().save_model()для сохранения объекта с помощьюModel.save().Например, чтобы прикрепить
request.userк объекту перед сохранением:from django.contrib import admin class ArticleAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): obj.user = request.user super().save_model(request, obj, form, change)
-
ModelAdmin.delete_model(request, obj) -
Метод
delete_modelполучаетHttpRequestи экземпляр модели. Переопределение этого метода позволяет выполнять операции до или после удаления. Вызовитеsuper().delete_model()для удаления объекта с помощьюModel.delete().
-
ModelAdmin.delete_queryset(request, queryset) -
Метод
delete_queryset()получаетHttpRequestиQuerySetобъектов, подлежащих удалению. Переопределите этот метод, чтобы настроить процесс удаления для действия «удалить выбранные объекты» действие.
-
ModelAdmin.save_formset(request, form, formset, change) -
Метод
save_formsetполучаетHttpRequest, экземпляр родительскогоModelFormи булево значение, определяющее, добавляется или изменяется родительский объект.Например, чтобы прикрепить
request.userк каждому изменённому экземпляру модели formset: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, список inline formset и булево значение, определяющее, добавляется или изменяется родительский объект. Здесь можно выполнить любые операции до или после сохранения для объектов, связанных с родителем. Обратите внимание, что на этом этапе родительский объект и его форма уже сохранены.
-
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, которые редактируются (или добавляются на форме добавления), и ожидается, что он вернёт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, которые редактируются (или добавляются на форме добавления), и ожидается, что он вернёт список полей, как описано вModelAdmin.exclude.
-
ModelAdmin.get_fields(request, obj=None) -
Метод
get_fieldsполучаетHttpRequestиobj, которые редактируются (или добавляются на форме добавления), и ожидается, что он вернёт список полей, как описано в разделеModelAdmin.fields.
-
ModelAdmin.get_fieldsets(request, obj=None) -
Метод
get_fieldsetsполучаетHttpRequestиobj, которые редактируются (или добавляются на форме добавления), и ожидается, что он вернёт список кортежей из двух элементов, где каждый кортеж представляет собой<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, которые редактируются (или добавляются на форме добавления), и ожидается, что он вернётlistилиtupleобъектовInlineModelAdmin, как описано в разделеInlineModelAdminниже. Например, следующее вернёт inline-объекты без стандартного фильтра, основанного на разрешениях добавления, изменения, удаления и просмотра: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]Если вы переопределяете этот метод, убедитесь, что возвращаемые inline-объекты являются экземплярами классов, определённых в
inlines, иначе при добавлении связанных объектов может возникнуть ошибка «Bad Request».
-
ModelAdmin.get_inlines(request, obj) -
Метод
get_inlinesполучаетHttpRequestиobj, которые редактируются (или добавляются на форме добавления), и ожидается, что он вернёт итерируемый объект inline-объектов. Вы можете переопределить этот метод, чтобы динамически добавлять inline-объекты на основе запроса или экземпляра модели вместо указания их вModelAdmin.inlines.
-
ModelAdmin.get_urls() -
Метод
get_urlsнаModelAdminвозвращает URL-адреса, которые должны использоваться для данного ModelAdmin, аналогично URLconf. Поэтому вы можете расширить их, как описано в диспетчере URL, используяAdminSite.admin_view()-обёртку для ваших представлений:from django.contrib import admin from django.template.response import TemplateResponse from django.urls import path class MyModelAdmin(admin.ModelAdmin): def get_urls(self): urls = super().get_urls() my_urls = [path("my_view/", self.admin_site.admin_view(self.my_view))] return my_urls + urls def my_view(self, request): # ... context = dict( # Include common variables for rendering the admin template. self.admin_site.each_context(request), # Anything else you want in the context... key=value, ) return TemplateResponse(request, "sometemplate.html", context)Если вы хотите использовать админ-макет, расширяйте от
admin/base_site.html:{% extends "admin/base_site.html" %} {% block content %} ... {% endblock %}Примечание
Обратите внимание, как функция
self.my_viewобернута вself.admin_site.admin_view. Это важно, так как это обеспечивает две вещи:- Проверки разрешений выполняются, гарантируя, что только активные сотрудники могут получить доступ к представлению.
- Декоратор
django.views.decorators.cache.never_cache()применяется для предотвращения кэширования, гарантируя, что возвращаемая информация актуальна.
Примечание
Обратите внимание, что пользовательские шаблоны включаются перед стандартными админ-URL-адресами: шаблоны админ-URL-адресов очень общие и будут соответствовать практически всему, поэтому вам обычно нужно предварить ваши пользовательские URL-адреса встроенными.
В этом примере,
my_viewбудет доступен по адресу/admin/myapp/mymodel/my_view/(предполагая, что админ-URL-адреса включены в/admin/.)Если страница кешируема, но вы всё равно хотите, чтобы выполнялась проверка разрешений, вы можете передать аргумент
cacheable=TrueвAdminSite.admin_view():path("my_view/", self.admin_site.admin_view(self.my_view, cacheable=True))Представления
ModelAdminимеют атрибутmodel_admin. Другие представленияAdminSiteимеют атрибутadmin_site.
-
ModelAdmin.get_form(request, obj=None, **kwargs) -
Возвращает класс
ModelFormдля использования в админских представлениях добавления и изменения, см.add_view()иchange_view().Базовая реализация использует
modelform_factory()для создания подклассаform, модифицированного атрибутами, такими какfieldsиexclude. Например, если вы хотите предложить дополнительные поля для суперпользователей, вы можете заменить базовый форму:class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): if request.user.is_superuser: kwargs["form"] = MySuperuserForm return super().get_form(request, obj, **kwargs)Вы также можете вернуть непосредственно пользовательский класс
ModelForm.
-
ModelAdmin.get_formsets_with_inlines(request, obj=None) -
Возвращает (
FormSet,InlineModelAdmin) пары для использования в представлениях добавления и изменения администратора.Например, если вы хотите отобразить определённую вложенную форму только в представлении изменения, вы можете переопределить
get_formsets_with_inlinesследующим образом:class MyModelAdmin(admin.ModelAdmin): inlines = [MyInline, SomeOtherInline] def get_formsets_with_inlines(self, request, obj=None): for inline in self.get_inline_instances(request, obj): # hide MyInline in the add view if not isinstance(inline, MyInline) or obj is not None: yield inline.get_formset(request, obj), inline
-
ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs) -
Метод
formfield_for_foreignkeyдляModelAdminпозволяет переопределить поле формы по умолчанию для внешнего ключа. Например, для возврата подмножества объектов для этого поля внешнего ключа на основе пользователя:class MyModelAdmin(admin.ModelAdmin): def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "car": kwargs["queryset"] = Car.objects.filter(owner=request.user) return super().formfield_for_foreignkey(db_field, request, **kwargs)Это использует экземпляр
HttpRequestдля фильтрации поля внешнего ключаCarтолько для отображения автомобилей, принадлежащих экземпляруUser.Для более сложных фильтров вы можете использовать метод
ModelForm.__init__()для фильтрации на основеinstanceвашей модели (см. Поля, обрабатывающие отношения). Например:class CountryAdminForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["capital"].queryset = self.instance.cities.all() class CountryAdmin(admin.ModelAdmin): form = CountryAdminForm
-
ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs) -
Как и метод
formfield_for_foreignkey, методformfield_for_manytomanyможно переопределить для изменения поля формы по умолчанию для поля «многие ко многим». Например, если владелец может владеть несколькими автомобилями, а автомобили могут принадлежать нескольким владельцам — отношение «многие ко многим» — вы можете отфильтровать поле внешнего ключаCarдля отображения только автомобилей, принадлежащихUser.class MyModelAdmin(admin.ModelAdmin): def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == "cars": kwargs["queryset"] = Car.objects.filter(owner=request.user) return super().formfield_for_manytomany(db_field, request, **kwargs)
-
ModelAdmin.formfield_for_choice_field(db_field, request, **kwargs) -
Как и методы
formfield_for_foreignkeyиformfield_for_manytomany, методformfield_for_choice_fieldможно переопределить для изменения поля формы по умолчанию для поля, имеющего объявленные значения. Например, если доступные значения для суперпользователя должны отличаться от значений для обычных сотрудников, вы можете действовать следующим образом:class MyModelAdmin(admin.ModelAdmin): def formfield_for_choice_field(self, db_field, request, **kwargs): if db_field.name == "status": kwargs["choices"] = [ ("accepted", "Accepted"), ("denied", "Denied"), ] if request.user.is_superuser: kwargs["choices"].append(("ready", "Ready for deployment")) return super().formfield_for_choice_field(db_field, request, **kwargs)Примечание
Любой атрибут
choicesформы, установленный для поля формы, будет ограничен только этим полем. Если соответствующее поле в модели имеет заданные значения, значения, предоставляемые для формы, должны быть допустимым подмножеством этих значений, в противном случае отправка формы завершится ошибкой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. См. пример настраиваемого 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) -
Способ настройки ключевых аргументов, передаваемых конструктору 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_pluralкаждой модели с количеством удаляемых объектов.perms_needed— множествоverbose_nameмоделей, которые пользователь не имеет права удалять.protected— список строк, представляющих все защищённые связанные объекты, которые не могут быть удалены. Список отображается в шаблоне.
Другие методы
-
ModelAdmin.add_view(request, form_url='', extra_context=None) -
Представление Django для страницы добавления экземпляра модели. См. примечание ниже.
-
ModelAdmin.change_view(request, object_id, form_url='', extra_context=None) -
Представление Django для страницы редактирования экземпляра модели. См. примечание ниже.
-
ModelAdmin.changelist_view(request, extra_context=None) -
Представление Django для страницы списка экземпляров модели/страницы действий. См. примечание ниже.
-
ModelAdmin.delete_view(request, object_id, extra_context=None) -
Представление Django для страницы подтверждения удаления экземпляра(ов) модели. См. примечание ниже.
-
ModelAdmin.history_view(request, object_id, extra_context=None) -
Представление Django для страницы, отображающей историю изменений для данного экземпляра модели.
Изменено в 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
JavaScript админки Django использует библиотеку jQuery.
Чтобы избежать конфликтов с пользовательскими скриптами или библиотеками, jQuery Django (версия 3.6.4) имеет имя пространства имён django.jQuery. Если вы хотите использовать jQuery в собственном JavaScript админки без включения второй копии, вы можете использовать объект django.jQuery в представлениях списка изменений и добавления/редактирования. Кроме того, ваши собственные формы или виджеты админки, зависящие от django.jQuery должны указывать js=['admin/js/jquery.init.js', …] при определении активов формы.
jQuery был обновлён с версии 3.6.0 до 3.6.4.
Класс 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'.
-
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 при определении поля многие-ко-многим.
Во-вторых, необходимо вручную исключить поле members. Django отображает виджет админки для поля многие-ко-многим в модели, которая определяет отношение (в данном случае, Group). Если вы хотите использовать встроенную модель для представления отношения многие-ко-многим, вы должны указать Django's админке, чтобы не отображать этот виджет — в противном случае у вас появятся два виджета на странице админки для управления отношением.
Обратите внимание, что при использовании этой техники сигналы 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 для более подробной информации.
Переопределение шаблонов админки
Вы можете переопределять многие шаблоны, используемые модулем админки для генерации различных страниц админского сайта. Вы даже можете переопределять некоторые из этих шаблонов для определенного приложения или определенной модели.
Настройка каталогов шаблонов админки вашего проекта
Файлы шаблонов админки находятся в каталоге django/contrib/admin/templates/admin.
Чтобы переопределить один или несколько из них, сначала создайте каталог admin в каталоге templates вашего проекта. Это может быть любой из каталогов, которые вы указали в параметре DIRS опции DjangoTemplates бэкенда в настройке TEMPLATES. Если вы настраивали опцию 'loaders', убедитесь, что 'django.template.loaders.filesystem.Loader' появляется перед 'django.template.loaders.app_directories.Loader', чтобы система загрузки шаблонов находила ваши пользовательские шаблоны раньше тех, которые включены с django.contrib.admin.
Внутри этого каталога admin создайте подкаталоги, названные в соответствии с вашими приложениями. Внутри этих подкаталогов создайте подкаталоги, названные в соответствии с вашими моделями. Обратите внимание, что приложение админки преобразует имя модели в нижний регистр при поиске каталога, поэтому убедитесь, что вы назвали каталог в нижнем регистре, если собираетесь запускать своё приложение на файловой системе с учетом регистра.
Чтобы переопределить шаблон админки для определенного приложения, скопируйте и отредактируйте шаблон из каталога django/contrib/admin/templates/admin и сохраните его в одном из только что созданных каталогов.
Например, если мы хотели добавить инструмент на страницу просмотра изменений для всех моделей в приложении под названием my_app, мы бы скопировали contrib/admin/templates/admin/change_list.html в каталог templates/admin/my_app/ нашего проекта и внесли необходимые изменения.
Если мы хотели добавить инструмент на страницу просмотра изменений только для определенной модели под названием «Page», мы бы скопировали тот же файл в каталог templates/admin/my_app/page нашего проекта.
Переопределение против замены шаблона админки
Из-за модульной структуры шаблонов админки, как правило, не нужно и не рекомендуется заменять весь шаблон. Практически всегда лучше переопределять только необходимый фрагмент шаблона.
Продолжая пример выше, мы хотим добавить новую ссылку рядом с инструментом History для модели Page. После изучения change_form.html мы определили, что нам нужно переопределить только блок object-tools-items. Вот наш новый шаблон change_form.html:
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
<li>
<a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% translate "History" %}</a>
</li>
<li>
<a href="mylink/" class="historylink">My Link</a>
</li>
{% if has_absolute_url %}
<li>
<a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% translate "View on site" %}</a>
</li>
{% endif %}
{% endblock %}
И всё! Если мы разместили этот файл в каталоге templates/admin/my_app, наша ссылка будет отображаться на странице изменения формы для всех моделей в приложении my_app.
Шаблоны, которые можно переопределить по приложению или модели
Не каждый шаблон в contrib/admin/templates/admin может быть переопределён по приложению или по модели. Следующие можно:
actions.htmlapp_index.htmlchange_form.htmlchange_form_object_tools.htmlchange_list.htmlchange_list_object_tools.htmlchange_list_results.htmldate_hierarchy.htmldelete_confirmation.htmlobject_history.htmlpagination.htmlpopup_response.htmlprepopulated_fields_js.htmlsearch_form.htmlsubmit_line.html
Для тех шаблонов, которые нельзя переопределить таким образом, вы всё ещё можете переопределить их для всего проекта, поместив новую версию в каталог templates/admin вашего проекта. Это особенно полезно для создания пользовательских страниц 404 и 500.
Примечание
Некоторые шаблоны админки, такие как change_list_results.html используются для рендеринга пользовательских тегов включения. Их можно переопределить, но в таких случаях вам, вероятно, будет лучше создать свою собственную версию интересующего вас тега и дать ему другое имя. Таким образом, вы сможете использовать его выборочно.
Шаблоны корневой и входной страницы
Если вы хотите изменить шаблоны главной страницы, входа или выхода, вам лучше создать свой экземпляр AdminSite (см. ниже) и изменить свойства AdminSite.index_template, AdminSite.login_template или AdminSite.logout_template.
Поддержка тем
Админка использует CSS-переменные для определения цветов и шрифтов. Это позволяет изменять темы, не переопределяя многие отдельные правила CSS. Например, если вы предпочтёте фиолетовый вместо синего, вы можете добавить переопределение шаблона admin/base.html в свой проект:
{% extends 'admin/base.html' %}
{% block extrastyle %}{{ block.super }}
<style>
: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 администрирование».
-
AdminSite.site_title -
Текст, отображаемый внизу каждой страницы администрирования
<title>(строка). По умолчанию это «Django администрирование сайта».
-
AdminSite.site_url -
URL для ссылки «Просмотреть сайт» вверху каждой страницы администрирования. По умолчанию,
site_urlэто/. Установите его вNoneдля удаления ссылки.Для сайтов, работающих на подпути, метод
each_context()проверяет, установлен ли текущий запросrequest.META['SCRIPT_NAME']и использует это значение, еслиsite_urlне установлено на значение, отличное от/.
-
AdminSite.index_title -
Текст, отображаемый вверху главной страницы администрирования (строка). По умолчанию это «Администрирование сайта».
-
AdminSite.index_template -
Путь к пользовательскому шаблону, который будет использоваться главной страницей администрирования.
-
AdminSite.app_index_template -
Путь к пользовательскому шаблону, который будет использоваться страницами администрирования приложений.
-
AdminSite.empty_value_display -
Строка, используемая для отображения пустых значений на странице списка изменений в админ-панели. По умолчанию — тире. Значение также может быть переопределено на основе каждого
ModelAdminи на основе настраиваемого поля вModelAdmin, установив атрибутempty_value_displayдля поля. См.ModelAdmin.empty_value_displayдля примеров.
-
Булево значение, определяющее, отображать ли боковую панель навигации на больших экранах. По умолчанию установлено в
True.
-
AdminSite.final_catch_all_view -
Булево значение, определяющее, добавлять ли конечную обработку всех запросов, перенаправляющую неавторизованных пользователей на страницу входа. По умолчанию установлено в
True.Предупреждение
Установка этого значения в
Falseне рекомендуется, так как представление защищает от потенциальной проблемы с конфиденциальностью перечисления моделей.
-
AdminSite.login_template -
Путь к пользовательскому шаблону, который будет использоваться для страницы входа в администрирование.
-
AdminSite.login_form -
Подкласс
AuthenticationForm, который будет использоваться для страницы входа в администрирование.
-
AdminSite.logout_template -
Путь к пользовательскому шаблону, который будет использоваться для страницы выхода из администрирования.
-
AdminSite.password_change_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: отслеживаниеdictadd,change,deleteиviewразрешений -
admin_url: URL админ-списка изменений для модели -
add_url: URL администрирования для добавления новой записи модели
-
-
is_popup: отображается ли текущая страница в всплывающем окне -
is_nav_sidebar_enabled:AdminSite.enable_nav_sidebar
-
-
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 по URL /admin/
# urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path("admin/", admin.site.urls),
]
Настройка класса AdminSite
Если вы хотите создать собственную админку с настраиваемым поведением, вы можете создать подкласс AdminSite и переопределить или добавить всё, что нужно. Затем создайте экземпляр подкласса AdminSite (так же, как вы создаёте любой другой класс Python) и зарегистрируйте ваши модели и подклассы ModelAdmin с ним вместо стандартной админки. Наконец, обновите myproject/urls.py для ссылки на ваш подкласс AdminSite.
myapp/admin.pyfrom django.contrib import admin
from .models import MyModel
class MyAdminSite(admin.AdminSite):
site_header = "Monty Python administration"
admin_site = MyAdminSite(name="myadmin")
admin_site.register(MyModel)
myproject/urls.pyfrom django.urls import path
from myapp.admin import admin_site
urlpatterns = [
path("myadmin/", admin_site.urls),
]
Обратите внимание, что вам, вероятно, не потребуется автоматическое обнаружение модулей admin при использовании собственного экземпляра AdminSite, так как вы, скорее всего, импортируете все модули admin каждого приложения в свой модуль myproject.admin. Это означает, что вам нужно указать 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin' в настройке INSTALLED_APPS.
Переопределение стандартной админки
Вы можете переопределить стандартную админку, установив атрибут 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 если ваше представление на странице админки или self.admin_site.name если ваше представление на странице с редактированием.
Добавление функции сброса пароля
Вы можете добавить функцию сброса пароля в админку, добавив несколько строк в ваш 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/ были перед строкой, включающей сам модуль админки).
Наличие имени URL admin_password_reset заставит появление ссылки «забыли пароль?» на стандартной странице входа в админку под полем для пароля.
LogEntry объекты
-
class models.LogEntry -
Класс
LogEntryотслеживает добавления, изменения и удаления объектов, выполненные через админский интерфейс.
LogEntry атрибуты
-
LogEntry.action_time -
Дата и время действия.
-
LogEntry.user -
Пользователь (
AUTH_USER_MODELэкземпляр), который выполнил действие.
-
LogEntry.content_type -
ContentTypeизменённого объекта.
-
LogEntry.object_id -
Текстовое представление первичного ключа изменённого объекта.
-
LogEntry.object_repr -
Объект
repr()после изменения.
-
LogEntry.action_flag -
Тип выполненного действия:
ADDITION,CHANGE,DELETION.Например, чтобы получить список всех добавлений, выполненных через админку:
from django.contrib.admin.models import ADDITION, LogEntry LogEntry.objects.filter(action_flag=ADDITION)
-
LogEntry.change_message -
Подробное описание изменения. В случае редактирования, например, сообщение содержит список изменённых полей. Сайт Django 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 для локализации | 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, а также в пространстве имён экземпляра, соответствующем имени экземпляра сайта.
Итак, если вам нужно получить ссылку на представление изменения для конкретного объекта 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.2/ref/contrib/admin/index/