Интерфейс администратора Django¶
Одна из сильных сторон Django – это автоматический интерфейс администратора. Он использует мета-данные модели чтобы предоставить многофункциональный, готовый к использованию интерфейс для работы с содержимым сайта. В этом разделе мы расскажем как установить, использовать и настроить интерфейс администратора Django.
У администратора есть множество возможностей для настройки, но остерегайтесь использовать исключительно эти приемы. Если вам необходимо предоставить более ориентированный на процессы интерфейс, который абстрагирует детали реализации таблиц и полей базы данных, то, вероятно, пришло время написать свои собственные представления.
В этом документе мы обсудим, как активировать, использовать и настраивать интерфейс администратора Django.
Обзор¶
Интерфейс администратора по умолчанию включен, если вы создавали проект командой startproject.
Если необходимо самостоятельно его включить, вот требования:
Интерфейс администратора имеет четыре зависимости -
django.contrib.auth,django.contrib.contenttypes,django.contrib.messagesanddjango.contrib.sessions. Если эти приложения не входят в списокINSTALLED_APPS, добавьте их.Настройте
DjangoTemplatesв настройкахTEMPLATESс помощьюdjango.template.context_processors.request,django.contrib.auth.context_processors.authиdjango.contrib.messages.context_processors.messagesв опции'context_processors'вOPTIONS.Если вы настроили параметр
MIDDLEWARE,django.contrib.sessions.middleware.SessionMiddleware,django.contrib.auth.middleware.AuthenticationMiddlewareиdjango.contrib.messages.middleware.MessageMiddlewareдолжны быть включены.
После всего это вы можете использовать интерфейс администратора Django посетив соответствующий URL (/admin/ по умолчанию).
Если вам нужно создать пользователя для входа в систему, используйте команду createsuperuser. По умолчанию для входа в систему администратора требуется, чтобы у пользователя для атрибута is_staff было установлено значение True.
Определите, какие модели будут редактироваться через интерфейс администратора.
Другие разделы¶
См.также
Информацию о настройке статических файлов (изображений, JavaScript и CSS) для интерфейса администратора на «боевом» сервере можно найти в разделе Обслуживание файлов.
Вопросы? Обратитесь к FAQ: Админка.
Объект ModelAdmin¶
- class ModelAdmin¶
Класс
ModelAdmin– это отображение модели в интерфейсе администратора. Его код добавляют обычно в файлadmin.pyвашего приложения. Давайте рассмотрим простой примерModelAdmin:from django.contrib import admin from myapp.models import Author class AuthorAdmin(admin.ModelAdmin): pass admin.site.register(Author, AuthorAdmin)
Нужен ли вообще вам объект
ModelAdmin?В этом примере, класс
ModelAdminне определяет никаких настроек (пока).В результате мы получим интерфейс предоставляемый по умолчанию. Если он вас устраивает, вы можете не определятьModelAdminсовсем и зарегистрировать модель безModelAdmin. Пример выше может выглядеть таким образом:from django.contrib import admin from myapp.models import Author admin.site.register(Author)
Декоратор для регистрации¶
- register(*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. Также принимается необязательный аргументsite, если вы не используете стандартныйAdminSite: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). Если вы используете Python 3 и не заботитесь о поддержке Python 2, вы можете использоватьsuper().__init__(*args, **kwargs). Иначе вам следует использоватьadmin.site.register()вместо декоратора.
Изучаем файлы админки¶
При добавлении 'django.contrib.admin' в INSTALLED_APPS setting, 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"
Поле в
list_filterможет указывать и на связанный объект используя__, например: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"]
Так как модель содержит только три поля,
name,titleиbirth_date, полученные формы будут содержать одинаковые поля.
- ModelAdmin.fields¶
Если вам необходимо внести небольшие изменения форму на странице редактирования и добавления, например, изменить список отображаемых полей, их порядок или сгруппировать их, вы можете использовать настройку
fields. Например, необходимо изменить форму модели из приложенияdjango.contrib.flatpages.models.FlatPage:class FlatPageAdmin(admin.ModelAdmin): fields = ["url", "title", "content"]
В примере выше будут отображаться только поля
url,titleиcontent.fieldsможет содержать поля указанные вModelAdmin.readonly_fields, они не будут доступны для редактирования.Для более сложных настроек используйте
fieldsets.Опция
fieldsпринимает те же типы значений, что иlist_display, за исключением того, что вызываемые объекты и поиск__для связанных полей не принимаются. Имена моделей и методов администрирования модели будут использоваться только в том случае, если они указаны вreadonly_fields.Чтобы поля отображались в одной строке, укажите их в кортеже вместе. В этом примере, поля
urlиtitleбудут отображаться в одном ряду, полеcontentбудет расположено ниже:class FlatPageAdmin(admin.ModelAdmin): fields = [("url", "title"), "content"]
Возможна путаница с опцией ModelAdmin.fieldsets.
Настройку
fieldsне следует путать с ключом словаряfieldsв настройкеfieldsets, описанной ниже.Если не определен ни атрибут
fields, ниfieldsets, Django покажет все поля сeditable=TrueкромеAutoField, в одном наборе полей в порядке, в котором они указанные в модели.
- ModelAdmin.fieldsets¶
Позволяет изменить макет страниц добавления и редактирования объекта.
fieldsets— это список из двух кортежей, в которых каждый из двух кортежей представляет<fieldset>на странице формы администратора. (<fieldset>— это «раздел» формы.)Эти 2 кортежа имеют формат «(имя, параметры поля)», где «имя» — это строка, представляющая заголовок набора полей, а «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"], }, ), ]
Этот пример будет выглядеть следующим образом:
Если не определен ни атрибут
fields, ниfieldsets, Django покажет все поля сeditable=TrueкромеAutoField, в одном наборе полей в порядке, в котором они указанные в модели.Словарь
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может содержать значения изModelAdmin.readonly_fields, чтобы отображать поля без возможности их редактирования.Добавление функции в
fieldsаналогично добавлению в параметрfields- функция должна быть указанна вreadonly_fields.
classesСписок или кортеж, содержащий дополнительные классы CSS, которые можно применить к набору полей. Сюда может входить любой пользовательский класс CSS, определенный в проекте, а также любой из классов CSS, предоставляемых Django. В таблице стилей CSS сайта администратора по умолчанию определены два особенно полезных класса:
collapseиwide.Например:
{ "classes": ["wide", "collapse"], }
Наборам полей со стилем «широкий» будет предоставлено дополнительное горизонтальное пространство в интерфейсе администратора. Наборы полей с именем и стилем «collapse» изначально будут свернуты с использованием расширяемого виджета с переключателем для переключения их видимости.
Changed in Django 5.1:fieldsets, использующие классcollapse, теперь используют элементы<details>и<summary>, при условии, что они определяютname.
descriptionСтрока необязательного дополнительного текста, которая будет отображаться вверху каждого набора полей под заголовком набора полей.
Заметим, что этот текст не будет экранирован. Это позволяет добавить вам HTML на страницу. Вы можете использовать обычный текст экранировав его функцией
django.utils.html.escape().
TabularInlineимеет ограниченную поддержкунаборов полейИспользование
fieldsetsсTabularInlineимеет ограниченную функциональность. Вы можете указать, какие поля будут отображаться и их порядок в макете TabularInline, определив поля в словаре field_options.Все остальные функции не поддерживаются. Это включает в себя использование
nameдля определения заголовка группы полей.
- ModelAdmin.filter_horizontal¶
По умолчанию, поле
ManyToManyFieldотображается как<select multiple>. Однако, это поле тяжело использовать при большом количестве объектов. ДобавивManyToManyFieldв этот атрибут, будет использоваться «виджет» с JavaScript фильтром для поиска. Смотрите описаниеfilter_verticalпро использование вертикального «виджета».
- ModelAdmin.filter_vertical¶
Аналогичен
filter_horizontal, но использует вертикальный «виджет».
- ModelAdmin.form¶
По умолчанию
ModelFormсоздается динамически для модели. Этот атрибут используется для определения формы на страницах добавления и редактирования. Вы можете указать собственный подклассModelFormдля переопределения этих страниц. Вы можете модифицировать форму, а не создавать с нуля свою, переопределив методModelAdmin.get_form().Пример смотрите в разделе Дополнительная проверка данных в интерфейсе администратора.
ModelAdmin.excludeимеет приоритет.Если и
ModelFormиModelAdminопределяют опциюexclude,ModelAdminбудет иметь больший приоритет:from django import forms from django.contrib import admin from myapp.models import Person class PersonForm(forms.ModelForm): class Meta: model = Person exclude = ["name"] class PersonAdmin(admin.ModelAdmin): exclude = ["age"] form = PersonForm
В этом примере, поле «age» не будет добавлено в форму в отличии от поля «name».
- ModelAdmin.formfield_overrides¶
Позволяет быстро изменить настройки отображения различных типов
Fieldв интерфейсе администратора.formfield_overrides– словарь указывающий параметры для классов полей, которые будут передаваться в конструкторы указанных полей.Все это звучит немного абстрактно, так что давайте рассмотрим пример. Самое распространенное применение
formfield_overridesэто переопределить «виджет» поля формы. Предположим у нас естьRichTextEditorWidget, который использует расширенное поля редактирования вместо<textarea>. Вот как мы может использовать его:from django.contrib import admin from django.db import models # Import our custom widget and our model from where they're defined from myapp.models import MyModel from myapp.widgets import RichTextEditorWidget class MyModelAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: {"widget": RichTextEditorWidget}, }
Заметим что ключ словаря класс поля, а не строка. Значение это словарь с аргументами. Это аргументы будут переданы в
__init__(). Подробности смотрите в разделе API форм.Предупреждение
Если вы хотите использовать собственный «виджет» для полей внешних ключей (например,
ForeignKeyилиManyToManyField), убедитесь что поле не добавлено вraw_id_fieldsилиradio_fields.formfield_overridesне позволяет переопределить «виджет» для полей изraw_id_fieldsилиradio_fields, потому чтоraw_id_fieldsиradio_fieldsпереопределяют виджет.
- ModelAdmin.inlines¶
Смотрите описание ниже
InlineModelAdmin, а такжеModelAdmin.get_formsets_with_inlines().
- ModelAdmin.list_display¶
list_displayуказывает какие поля отображать на странице списка объектов.Например:
list_display = ["first_name", "last_name"]
Если
list_displayне указан, Django отобразить только результат__str__()``(``__unicode__()для Python 2) объекта.Существует пять типов значений, которые можно использовать в list_display. Все, кроме самых простых, могут использовать декоратор
display(), который используется для настройки представления поля:Поле модели. Например:
class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "last_name"]
Имя связанного поля с использованием нотации
__. Например:class PersonAdmin(admin.ModelAdmin): list_display = ["city__name"]
Функция, которая принимает один аргумент - объект модели. Например:
@admin.display(description="Name") def upper_case_name(obj): return f"{obj.first_name} {obj.last_name}".upper() class PersonAdmin(admin.ModelAdmin): list_display = [upper_case_name]
Функция, которая принимает один аргумент - объект модели. Например:
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()
Название атрибута
ModelAdmin. Работает так же, как и функция. Например: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"]
Changed in Django 5.1:Была добавлена поддержка использования поиска
__при выборе связанных полей.Несколько особенностей
list_display:Если указано поле
ForeignKey, Django покажет результат__str__()(__unicode__()для Python 2) связанного объекта.ManyToManyFieldне поддерживается, так как это влечет к созданию SQL запроса для каждого объекта. Если вам необходимо сделать это в любом случае, создайте метод модели и используйте его вlist_display. (Смотрите ниже подробности про использование методов вlist_display.)Если поле имеет тип BooleanField, Django отобразит красивый значок «да», «нет» или «неизвестно» вместо «True», «False» или «None».
Если используется метод модели,
ModelAdminили функция, Django по умолчанию экранирует результат. Если вам нужно экранировать данные, вводимые пользователем, и не экранировать собственные теги, используйте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)"
Вы можете также использовать
AdminSite.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со значением, установленным вПравда: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__()(__unicode__()в Python 2) можно использовать вlist_displayкак и любой другой метод модели:list_display = ["__str__", "some_other_field"]
Обычно элементы
list_display, которые не являются полями модели, не могу быть использованы при сортировке (так как Django выполняет сортировку на уровне базы данных).Однако, если элемент list_display представляет определенное поле базы данных, вы можете указать этот факт, используя декоратор
display()для метода, передав аргументordering:from django.contrib import admin from django.db import models from django.utils.html import format_html class Person(models.Model): first_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) @admin.display(ordering="first_name") def colored_first_name(self): return format_html( '<span style="color: #{};">{}</span>', self.color_code, self.first_name, ) class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "colored_first_name"]
В этом примере Django будет использовать поле
first_nameпри сортировке поcolored_first_name.Чтобы указать порядок убывания с помощью аргумента «ordering», вы можете использовать префикс дефиса в имени поля. Используя приведенный выше пример, это будет выглядеть так:
@admin.display(ordering="-first_name") def colored_first_name(self): ...
Аргумент ordering поддерживает поиск запросов для сортировки по значениям в связанных моделях. Этот пример включает столбец «имя автора» в список и позволяет сортировать его по имени:
class Blog(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey(Person, on_delete=models.CASCADE) class BlogAdmin(admin.ModelAdmin): list_display = ["title", "author", "author_first_name"] @admin.display(ordering="author__first_name") def author_first_name(self, obj): return obj.author.first_name
Выражения запроса можно использовать с аргументом
ordering:from django.db.models import Value from django.db.models.functions import Concat class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @admin.display(ordering=Concat("first_name", Value(" "), "last_name")) def full_name(self): return self.first_name + " " + self.last_name
Элементы
list_displayтакже могут быть свойствами:class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @property @admin.display( ordering="last_name", description="Full name of the person", boolean=False, ) def full_name(self): return self.first_name + " " + self.last_name class PersonAdmin(admin.ModelAdmin): list_display = ["full_name"]
Обратите внимание, что
@propertyдолжен быть выше@display. Если вы используете старый способ — напрямую устанавливая атрибуты, связанные с отображением, а не используя декораторdisplay(), имейте в виду, что необходимо использовать функциюproperty(), а не декоратор@property:def my_property(self): return self.first_name + " " + self.last_name my_property.short_description = "Full name of the person" my_property.admin_order_field = "last_name" my_property.boolean = False full_name = property(my_property)
Changed in Django 5.0:Добавлена поддержка логического атрибута свойств.
Названия полей из
list_displayбудут использованы в CSS классах, форма будет содержать классcolumn-<field_name>для каждого элемента<th>. Так можно определить ширину полей через CSS стили.Django попытается интерпретировать каждый элемент
list_displayв следующем порядке:Поле модели или из связанного поля.
Метод или любой другой вызываемый объект.
Строка, представляющая атрибут
ModelAdmin.Строка, представляющая атрибут модели.
Например, если существует поле модели
first_nameи атрибутModelAdmin, будет использоваться поле модели.
- ModelAdmin.list_display_links¶
Используйте
list_display_links, чтобы указать какие поля вlist_displayбудут ссылками на страницу редактирования объекта.По умолчанию, на страницу редактирования объекта будет вести ссылка в первой колонке – первое поле в
list_display. Ноlist_display_linksпозволяет изменить это поведение:Можно указать
None, чтобы убрать ссылки.Укажите список или кортеж полей (так же как и в
list_display) чьи колонки должны быть ссылками на страницу редактирования.Вы можете указывать одно или несколько полей. Пока указанные поля входят в
list_display, Django безразлично сколько их. Единственное требование: для использованияlist_display_linksвы должны указатьlist_display.
В этом примере поля
first_nameиlast_nameбудут отображаться как ссылки на страницу редактирования объекта:class PersonAdmin(admin.ModelAdmin): list_display = ["first_name", "last_name", "birthday"] list_display_links = ["first_name", "last_name"]
В этом примере список объектов будет без ссылок:
class AuditEntryAdmin(admin.ModelAdmin): list_display = ["timestamp", "message"] list_display_links = None
- ModelAdmin.list_editable¶
Укажите в
list_editableсписок полей, которые можно будет редактировать на странице списка объектов. То есть, поля изlist_editableбудут отображаться как поля формы позволяя пользователям изменять значения и сохранять изменения для всех строк сразу.Примечание
list_editableвзаимодействует с другими настройками следующим образом:Поле из
list_editableдолжно входить вlist_display. Вы не можете редактировать поле, которое не отображается!Поле не может быть в
list_editableиlist_display_linksвместе – поле не может быть ссылкой и полем формы.
Вы получите ошибку проверки если нарушите эти правила.
- ModelAdmin.list_filter¶
Установите
list_filter, чтобы активировать фильтры на правой боковой панели страницы списка изменений администратора.В простейшем случае
list_filterпринимает список или кортеж имен полей для активации фильтрации, но доступны и несколько более продвинутых опций. Подробности смотрите в Фильтры списка ModelAdmin.
- ModelAdmin.list_max_show_all¶
Используйте
list_max_show_all, чтобы указать количество объектов на странице списка объектов при выборе «Показать все». Интерфейс администратора покажет ссылку «Показать все» только если общее количество объектов меньше или равно этому значению. По умолчанию равно200.
- ModelAdmin.list_per_page¶
Используйте
list_per_page, чтобы определить количество объектов на одной странице при отображении списка объектов. По умолчанию равно100.
Используйте
list_select_related, чтобы указать Django использоватьselect_related()при выборе объектов для страницы отображения объектов. Это может сократить количество запросов на этой странице.Значение должно быть булево, список или кортеж. По умолчанию равно
False.При
True,select_related()всегда будет использоваться. ПриFalse, Django найдет вlist_displayвсеForeignKeyи будет использовать их сselect_related().Если вам нужен больший контроль, используйте список или кортеж для
list_select_related. Пустой кортеж укажет не использоватьselect_related. Не пустой кортеж будет передан как параметр дляselect_related. Например:class ArticleAdmin(admin.ModelAdmin): list_select_related = ["author", "category"]
вызовет
select_related('author', 'category').Если вам необходимы динамические значения, которые зависят от текущего запроса, вы можете определить метод
get_list_select_related().Примечание
ModelAdminигнорирует этот атрибут, когдаselect_lated()уже был вызван вQuerySetсписка изменений.
- ModelAdmin.ordering¶
orderingпозволяет определить сортировку на странице списка объектов. Это должен быть список или кортеж в формате аналогичном параметруordering.Если атрибут не указана, Django будет использовать сортировку по умолчанию модели.
Если вам необходима динамическая сортировка (например, в зависимости от пользователя или текущего языка) вы можете определить метод
get_ordering().Вопросы производительности при упорядочивании и сортировке
Чтобы обеспечить детерминированный порядок результатов, список изменений добавляет к порядку
pk, если не удается найти один или уникальный набор полей, обеспечивающих полный порядок.Например, если порядок по умолчанию осуществляется по неуникальному полю
name, то список изменений сортируется поnameиpk. Это может работать плохо, если у вас много строк и нет индекса дляnameиpk.
- ModelAdmin.paginator¶
Класс, используемый для создания постраничного отображения. По умолчанию используется
django.core.paginator.Paginator. Если конструктор вашего класса принимает параметры отличные отdjango.core.paginator.Paginator, вам необходимо также переопределить методModelAdmin.get_paginator().
- ModelAdmin.prepopulated_fields¶
prepopulated_fieldsпозволяет определить поля, которые получают значение основываясь на значениях других полей:class ArticleAdmin(admin.ModelAdmin): prepopulated_fields = {"slug": ["title"]}
Если установлено, данные поля будут использовать немного JavaScript для заполнения из назначенных полей. Основное использование этой функции — автоматическое создание значения для полей SlugField из одного или нескольких других полей. Сгенерированное значение создается путем объединения значений исходных полей, а затем путем преобразования этого результата в действительный фрагмент (например, путем замены пробелов тире и строчных букв ASCII).
Предварительно заполненные поля не изменяются с помощью JavaScript после сохранения значения. Обычно нежелательно, чтобы слаги менялись (это может привести к изменению URL-адреса объекта, если в нем используется слаг).
prepopulated_fieldsне принимает поляDateTimeField,ForeignKeyилиManyToManyField.
- ModelAdmin.preserve_filters¶
По умолчанию примененные фильтры сохраняются в виде списка после создания, редактирования или удаления объекта. Вы можете очистить фильтры, установив для этого атрибута значение «False».
- ModelAdmin.show_facets¶
- New in Django 5.0.
Определяет, отображается ли количество фасетов для фильтров в списке изменений администратора. По умолчанию:
ShowFacets.ALLOW.При отображении количество фасетов обновляется в соответствии с примененными в данный момент фильтрами.
- class ShowFacets¶
- New in Django 5.0.
Перечисление разрешенных значений для
ModelAdmin.show_facets.- ALWAYS¶
Всегда показывать количество фасетов.
- ALLOW¶
Показывать количество фасетов, если указан параметр строки запроса
_facets.
- NEVER¶
Никогда не показывайте количество фасетов.
Установите для
show_facetsжелаемое значениеShowFacets. Например, чтобы всегда отображать количество фасетов без необходимости предоставления параметра запроса:from django.contrib import admin class MyModelAdmin(admin.ModelAdmin): ... # Have facets always shown for this model admin. show_facets = admin.ShowFacets.ALWAYS
Вопросы производительности с фасетами
Включение фасетных фильтров увеличит количество запросов на странице списка изменений администратора в соответствии с количеством фильтров. Эти запросы могут вызвать проблемы с производительностью, особенно для больших наборов данных. В этих случаях может оказаться целесообразным установить для
show_facetsзначениеShowFacets.NEVER, чтобы полностью отключить фасетирование.
- ModelAdmin.radio_fields¶
По умолчанию Django использует <select> для полей
ForeignKeyили тех, которые содержатchoices. Ели поле указанно вradio_fields, Django будет использовать радио кнопки. Предположим чтоgroupполеForeignKeyв моделиPerson:class PersonAdmin(admin.ModelAdmin): radio_fields = {"group": admin.VERTICAL}
Вы можете использовать
HORIZONTALилиVERTICALиз модуляdjango.contrib.admin.Не добавляйте в
radio_fieldsполя, которые не являютсяForeignKeyили не содержатchoices.
- ModelAdmin.autocomplete_fields¶
autocomplete_fields— это список полейForeignKeyи/илиManyToManyField, которые вы хотите изменить на ``Select2 <https://select2.org/>`_ входные данные автозаполнения.По умолчанию Django использует <select> для полей
ForeignKey. Если связанных объектов очень много, создание <select> может быть очень затратным процессом.Ввод Select2 похож на ввод по умолчанию, но имеет функцию поиска, которая загружает параметры асинхронно. Это быстрее и удобнее для пользователя, если связанная модель имеет много экземпляров.
Вы должны определить
search_fieldsвModelAdminсвязанного объекта, поскольку он используется при поиске с автозаполнением.Чтобы избежать несанкционированного раскрытия данных, пользователи должны иметь разрешение на просмотр или изменение связанного объекта, чтобы использовать автозаполнение.
Порядок и нумерация результатов контролируются соответствующими методами
get_ordering()иget_paginator()ModelAdmin.В следующем примере ChoiceAdmin имеет поле автозаполнения для ForeignKey в вопросе. Результаты фильтруются по полю «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. Если связанных объектов очень много, создание <select> может быть очень затратным процессом.raw_id_fieldsсодержит список полей, которые будут использовать полеInputдляForeignKeyилиManyToManyField:class ArticleAdmin(admin.ModelAdmin): raw_id_fields = ["newspaper"]
Виджет поля для
raw_id_fieldsбудет содержать значение первичного ключа дляForeignKeyили список ключей дляManyToManyField. Возле поля есть кнопка поиска и выбора связанных объектов:
- ModelAdmin.readonly_fields¶
По умолчанию интерфейс администратора отображает все поля как редактируемые. Поля указанные в этой настройке (которая является
listилиtuple) будут отображаться значение без возможности редактировать, они также будут исключены изModelFormиспользуемой для создания и редактирования объектов. Однако, если вы определяете аргументModelAdmin.fieldsилиModelAdmin.fieldsetsполя для чтения должны быть в них указаны (иначе они будут проигнорированы).Если
readonly_fieldsиспользуется без определения порядка полей через атрибутыModelAdmin.fieldsилиModelAdmin.fieldsets, поля из этой настройки будут отображаться после редактируемых полей.Read-only поле может показывать данные не только поля модели, но и метода, а также метода определенного в подклассе
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равенFalse.
- ModelAdmin.save_on_top¶
Укажите
save_on_top, чтобы добавить кнопки сохранения в верхней части страницы редактирования объекта.По умолчанию кнопки сохранения отображаются под формой. Если указать
save_on_top, кнопки будут отображаться и сверху и снизу.По умолчанию
save_on_topравенFalse.
- ModelAdmin.search_fields¶
search_fieldsпозволяет добавить поиск на страницу списка объектов. Этот атрибут должен содержать список полей, которые будут использоваться при поиске.Эти поля должны быть текстовыми, таким как
CharFieldилиTextField. Вы можете указать поля из связанных объектов используя__:search_fields = ["foreign_key__related_fieldname"]
Например, у нас есть модель записи в блоге с полем автора. Следующая настройка позволит искать записи по email адресу автора:
search_fields = ["user__email"]
При поиске Django разбивает поисковый запрос на слова и возвращает объекты, которые содержат эти слова в одном из указанных в
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 выполнит эквивалент этого предложения SQLWHERE:WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')
Если вы не хотите использовать «icontains» для поиска, вы можете использовать любой поиск, добавив его в поле. Например, вы можете использовать
exact, установив дляsearch_fieldsзначение['first_name__exact'].Также доступны некоторые (более старые) сочетания клавиш для задания поиска по полю. Вы можете префикс поля в
search_fieldsследующими символами, и это эквивалентно добавлению__<lookup>к полю:Префикс
Искать
^
=
@
поискНикто
Вы можете переопределить метод
ModelAdmin.get_search_results(), чтобы указать дополнительные параметры при поиске, или переопределить механизм поиска.
- ModelAdmin.search_help_text¶
Установите
search_help_text, чтобы указать описательный текст для поля поиска, который будет отображаться под ним.
- ModelAdmin.show_full_result_count¶
show_full_result_countуказывает показывать ли количество всех объектов при фильтрации (например99 results (103 total)). Если опция равнаFalse, будет показан подобный текст:99 results (Show all).По умолчанию
show_full_result_count=Trueвыполняет запрос, чтобы получить количество всех объектов, что может работать очень медленно для таблиц с большим количеством данных.
- ModelAdmin.sortable_by¶
По умолчанию страница списка изменений позволяет сортировать по всем полям модели (и вызываемым объектам, которые используют аргумент
orderingдля декоратораdisplay()или имеют атрибутadmin_order_field), указанный вlist_display.Если вы хотите отключить сортировку для некоторых столбцов, установите для
sortable_byколлекцию (например,list,tupleилиset) подмножестваlist_display, которую вы хотите сортировать. Пустая коллекция отключает сортировку для всех столбцов.Если вам необходимы динамические значения, которые зависят от текущего запроса, вы можете определить метод
get_list_select_related().
- ModelAdmin.view_on_site¶
view_on_siteопределять показывать ли ссылку «Посмотреть на сайте». Эта ссылка должна вести на страницу сохраненного объекта.Можно указать булево или функцию. При
True(по умолчанию) будет использоваться методget_absolute_url()объекта для получения ссылки.Если модель содержит метод
get_absolute_url(), но вы не хотите показывать кнопку «Посмотреть на сайте», укажитеFalseвview_on_site: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¶
Путь к шаблону, который используется
change_view().
Методы ModelAdmin¶
Предупреждение
Методы ModelAdmin.save_model() и ModelAdmin.delete_model() должны сохранять/удалять объект. Их задача выполнять дополнительные операции, а не разрешать/запрещать операции удаления/сохранения.
- ModelAdmin.save_model(request, obj, form, change)¶
Метод
save_modelпринимает объектHttpRequest, экземпляр модели, экземплярModelFormи булево значение указывающее создан объект или изменяется. В этом методе вы может выполнить дополнительные операции до или после сохранения.Например, добавление
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и экземпляр модели, который удаляется. В этом методе вы может выполнить дополнительные операции до или после удаления.
- ModelAdmin.delete_queryset(request, queryset)¶
Метод
delete_modelпринимает объектHttpRequestи экземпляр модели, который удаляется. В этом методе вы может выполнить дополнительные операции до или после удаления.
- ModelAdmin.save_formset(request, form, formset, change)¶
Метод
save_formsetпринимает объектHttpRequest,ModelFormродительского объекта, «formset» связанных объектов и булево значение указывающее создан родительский объект или изменяется.Например, добавление
request.userк каждому объекту, измененному в наборе форм:class ArticleAdmin(admin.ModelAdmin): def save_formset(self, request, form, formset, change): instances = formset.save(commit=False) for obj in formset.deleted_objects: obj.delete() for instance in instances: instance.user = request.user instance.save() formset.save_m2m()
Смотрите также Сохранение объектов набора форм.
Предупреждение
Все перехватчики, возвращающие свойство ModelAdmin, возвращают само свойство, а не копию его значения. Динамическое изменение значения может привести к неожиданным результатам.
Давайте возьмем ModelAdmin.get_readonly_fields() в качестве примера:
class PersonAdmin(admin.ModelAdmin):
readonly_fields = ["name"]
def get_readonly_fields(self, request, obj=None):
readonly = super().get_readonly_fields(request, obj)
if not request.user.is_superuser:
readonly.append("age") # Edits the class attribute.
return readonly
В результате readonly_fields становится ["name", "age", "age", ...] даже для суперпользователя, так как "age" добавляется каждый раз, когда пользователь, не являющийся суперпользователем, посещает страницу.
- ModelAdmin.get_ordering(request)¶
Метод
get_orderingпринимает объектrequestи должен вернутьlistилиtupleс параметрами сортировки аналогично атрибутуordering. Например:class PersonAdmin(admin.ModelAdmin): def get_ordering(self, request): if request.user.is_superuser: return ["name", "rank"] else: return ["name"]
- ModelAdmin.get_search_results(request, queryset, search_term)¶
Метод
get_search_resultsфильтрует список объектов в соответствии с параметрами поиска. Он принимает запрос,querysetобъектов, и параметры поиска указанные пользователем. Возвращает кортеж содержащий полученныйquerysetи булево указывающее может ли результат содержать одинаковые значения.По умолчанию выполняется поиск по полям из
ModelAdmin.search_fields.Этот метод можно переопределить вашим собственным методом поиска. Например, вы можете выполнить поиск по целочисленному полю или использовать внешний инструмент, такой как Solr или Haystack. Вы должны определить, могут ли изменения набора запросов, реализованные вашим методом поиска, привести к появлению дубликатов в результатах, и вернуть «True» во втором элементе возвращаемого значения.
Например, для поиска по численным полям можно сделать:
class PersonAdmin(admin.ModelAdmin): list_display = ["name", "age"] search_fields = ["name"] def get_search_results(self, request, queryset, search_term): queryset, may_have_duplicates = super().get_search_results( request, queryset, search_term, ) try: search_term_as_int = int(search_term) except ValueError: pass else: queryset |= self.model.objects.filter(age=search_term_as_int) return queryset, may_have_duplicates
Эта реализация более эффективна, чем
search_fields = ('name', '=age'), которая приводит к сравнению строк для числового поля, например... OR UPPER("polls_choice"."votes"::text) = UPPER('4')в PostgreSQL.
Метод
save_relatedпринимает объектHttpRequest, родительскую формуModelForm, список «inline formsets» и булево значение указывающее создан родительский объект или изменяется. Вы можете выполнить дополнительные операции перед и после сохранения объектов. Заметим, что к этому моменту родительский объект и его формы уже будут сохранены.
- ModelAdmin.get_autocomplete_fields(request)¶
Метод
get_list_displayпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернутьlistилиtupleсодержащий список полей, которые будут отображаться на странице списка объектов как описано в разделеModelAdmin.list_display.
- ModelAdmin.get_readonly_fields(request, obj=None)¶
Метод
get_readonly_fieldsпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернутьlistилиtupleсодержащий список полей, которые будут отображаться только для чтения как описано в разделеModelAdmin.readonly_fields.
- ModelAdmin.get_prepopulated_fields(request, obj=None)¶
Метод
get_prepopulated_fieldsпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернуть словарь полей аналогичныйModelAdmin.prepopulated_fields.
- ModelAdmin.get_list_display(request)¶
Метод
get_list_displayпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернуть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_fieldsпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернуть список полей аналогичныйModelAdmin.fields.
- ModelAdmin.get_fields(request, obj=None)¶
Метод
get_fieldsпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернуть список полей аналогичныйModelAdmin.fields.
- ModelAdmin.get_fieldsets(request, obj=None)¶
Методу get_fieldsets присваиваются редактируемые HttpRequest и obj (или None в форме добавления), и ожидается, что он вернет список из двух кортежей, в которых каждый два кортежа представляет собой
<fieldset>на странице формы администратора, как описано выше в разделеModelAdmin.fieldsets.
- ModelAdmin.get_list_filter(request)¶
Метод
get_list_filterпринимаетHttpRequestдолжен вернуть значение формата, соответствующего параметруlist_filter.
Метод
get_list_select_relatedпринимаетHttpRequestдолжен вернуть значение формата, соответствующего параметруlist_filter.
- ModelAdmin.get_search_fields(request)¶
Метод
get_search_fieldsпринимаетHttpRequestдолжен вернуть значение формата, соответствующего параметруsearch_fields.
- ModelAdmin.get_sortable_by(request)¶
Метод
get_list_displayпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернутьlistилиtupleсодержащий список полей, которые будут отображаться на странице списка объектов как описано в разделеModelAdmin.list_display.Его реализация по умолчанию возвращает
sortable_by, если он установлен, в противном случае она передаетсяget_list_display().Например, чтобы запретить сортировку одного или нескольких столбцов:
class PersonAdmin(admin.ModelAdmin): def get_sortable_by(self, request): return {*self.get_list_display(request)} - {"rank"}
- ModelAdmin.get_inline_instances(request, obj=None)¶
Метод
get_inline_instancesпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернутьlistилиtupleсодержащий объектыInlineModelAdmin, как описано в разделе оInlineModelAdmin. Например, следующий метод вернет все «inlines» без проверки прав на добавление, изменение или удаление связанных объектов.class MyModelAdmin(admin.ModelAdmin): inlines = [MyInline] def get_inline_instances(self, request, obj=None): return [inline(self.model, self.admin_site) for inline in self.inlines]
Если вы переопределяете этот метод, убедитесь, что возвращаемы объекты являются экземплярами одного из классов из
inlines, иначе можете получить ошибку «Bad Request» при добавлении связанного объекта.
- ModelAdmin.get_inlines(request, obj)¶
Метод
get_fieldsпринимает объектHttpRequestи редактируемый объектobj(илиNoneдля формы создания нового объекта) и должен вернуть список полей аналогичныйModelAdmin.fields.
- 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-ам. Поэтому желательно добавлять собственные 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)¶
Выполняет yield по парам (
FormSet,InlineModelAdmin), чтобы вернуть набор форм для страницы создания и изменения.Например, если некоторый «inline» необходимо отображать только при редактировании, можно переопределить метод
get_formsets_with_inlines:class MyModelAdmin(admin.ModelAdmin): inlines = [MyInline, SomeOtherInline] def get_formsets_with_inlines(self, request, obj=None): for inline in self.get_inline_instances(request, obj): # hide MyInline in the add view if not isinstance(inline, MyInline) or obj is not None: yield inline.get_formset(request, obj), inline
- ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs)¶
Метод
formfield_for_foreignkeyпозволяет вам переопределить поле для внешнего ключа. Например, изменить выбор объектов в зависимости от пользователя: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по текущему пользователю.Для более сложных фильтров вы можете использовать метод ModelForm.__init__() для фильтрации на основе экземпляра вашей модели (см. fields-that-handle-relationships). Например:
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, чтобы отображать машины только текущего пользователя: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позволяет переопределить поле формы для поля модели, которое содержитchoices. Например, если главному администратору необходимо отображать варианты значений отличные от вариантов ответов для остальных пользователей:class MyModelAdmin(admin.ModelAdmin): def formfield_for_choice_field(self, db_field, request, **kwargs): if db_field.name == "status": kwargs["choices"] = [ ("accepted", "Accepted"), ("denied", "Denied"), ] if request.user.is_superuser: kwargs["choices"].append(("ready", "Ready for deployment")) return super().formfield_for_choice_field(db_field, request, **kwargs)
ограничения
выбораАтрибут
choices, указанный в поле форме, влияет только на проверку поля формы. Если соответствующее поле модели содержитchoices,choicesв поле формы должен быть его подмножеством, иначе вы получитеValidationErrorпри проверке модели.
- ModelAdmin.get_changelist(request, **kwargs)¶
Возвращает класс
Changelist, который используется для отображения списка объекта. По умолчанию, используетсяdjango.contrib.admin.views.main.ChangeList. Унаследовав этот класс вы можете переопределить поведение этой страницы.
- ModelAdmin.get_changelist_form(request, **kwargs)¶
Возвращает подкласс
ModelFormдляFormset, который будет использоваться на странице списка объектов. Например:from django import forms class MyForm(forms.ModelForm): pass class MyModelAdmin(admin.ModelAdmin): def get_changelist_form(self, request, **kwargs): return MyForm
- ModelAdmin.get_changelist_formset(request, **kwargs)¶
Возвращает ModelFormSet, который будет использоваться на странице списка объектов, если включен
list_editable. Например:from django.forms import BaseModelFormSet class MyAdminFormSet(BaseModelFormSet): pass class MyModelAdmin(admin.ModelAdmin): def get_changelist_formset(self, request, **kwargs): kwargs["formset"] = MyAdminFormSet return super().get_changelist_formset(request, **kwargs)
- ModelAdmin.lookup_allowed(lookup, value, request)¶
Объекты на странице списка изменений можно фильтровать с помощью поиска по строке запроса URL-адреса. Вот как работает, например,
list_filter. Поиск аналогичен тому, что используется вQuerySet.filter()(например,user__email=user@example.com). Поскольку пользователь может манипулировать поисковыми запросами в строке запроса, их необходимо очистить, чтобы предотвратить несанкционированное раскрытие данных.Методу
lookup_allowed()присваивается путь поиска из строки запроса (например,'user__email'), соответствующее значение (например,'user@example.com') и запрос, и он возвращает логическое значение, указывающее, разрешена ли фильтрацияQuerySetсписка изменений с использованием параметров. Еслиlookup_allowed()возвращаетFalse, вызываетсяDisallowedModelAdminLookup(подклассSuspiciousOperation).По умолчанию
lookup_allowed()разрешает доступ к локальным полям модели, путям к полям, используемым вlist_filter(но не путям изget_list_filter()), а также поискам, необходимым для правильной работыlimit_choices_toвraw_id_fields.Переопределите этот метод, чтобы настроить поиск, разрешенный для вашего подкласса
ModelAdmin.Changed in Django 5.0:Был добавлен аргумент
request.
- ModelAdmin.has_view_permission(request, obj=None)¶
Должен возвращать
True, если пользователю позволено изменять объект, иначеFalse. ЕслиobjравенNone, должен вернутьTrueилиFalse, указывая может ли пользователь изменить какой-либо объект данного типа.Реализация по умолчанию возвращает True, если у пользователя есть разрешение «изменение» или «просмотр».
- ModelAdmin.has_add_permission(request)¶
Должен возвращать
True, если пользователю позволено добавлять новый объект, иначеFalse.
- ModelAdmin.has_change_permission(request, obj=None)¶
Должен возвращать
True, если пользователю позволено изменять объект, иначеFalse. ЕслиobjравенNone, должен вернутьTrueилиFalse, указывая может ли пользователь изменить какой-либо объект данного типа.
- ModelAdmin.has_delete_permission(request, obj=None)¶
Должен вернуть
True, если пользователю позволено удалять объект, иначеFalse. ЕслиobjравенNone, должен вернутьTrueилиFalse, указывая может ли пользователь удалить какой-либо объект данного типа.
- ModelAdmin.has_module_permission(request)¶
Должен возвращать
True, если модуль можно показывать на главной странице и у пользователя есть доступ к главной странице модуля, иначеFalse. По умолчанию используетUser.has_module_perms(). Не ограничивает доступ к представлениям добавления, изменения и удаления, для этого используются методыhas_add_permission(),has_change_permission()иhas_delete_permission().
- ModelAdmin.get_queryset(request)¶
Метод
get_querysetвозвращает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)¶
Перехватчик для настройки аргументов ключевого слова, передаваемых конструктору набора форм. Например, чтобы передать
запросв формы набора форм: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}, }
Вы также можете использовать его для установки
начальногодля форм набора форм.
- 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()и «удалить выбранное» action.Аргумент objs представляет собой однородную итерацию объектов (QuerySet или список экземпляров модели), которые необходимо удалить, а аргумент request представляет собой
HttpRequest.Этот метод должен возвращать кортеж из четырех строк
(deleted_objects, model_count, perms_needed, protected).deleted_objects— это список строк, представляющих все объекты, которые будут удалены. Если есть какие-либо связанные объекты, которые необходимо удалить, список является вложенным и включает в себя эти связанные объекты. Список форматируется в шаблоне с использованием фильтраunordered_list.model_count— это словарь, сопоставляющийverbose_name_pluralкаждой модели с количеством объектов, которые будут удалены.perms_needed— это наборverbose_nameмоделей, на удаление которых у пользователя нет разрешения.protected— это список строк, представляющих все защищенные связанные объекты, которые нельзя удалить. Список отображается в шаблоне.
Остальные методы¶
- ModelAdmin.add_view(request, form_url='', extra_context=None)¶
Представление Django для страницы добавления объекта модели. Смотрите описание ниже.
- ModelAdmin.change_view(request, object_id, form_url='', extra_context=None)¶
Представление Django для страницы редактирования объекта модели. Смотрите описание ниже.
- ModelAdmin.changelist_view(request, extra_context=None)¶
Представление Django для страницы отображения всех объектов модели. Смотрите описание ниже.
- ModelAdmin.delete_view(request, object_id, extra_context=None)¶
Представление Django для страницы подтверждения удаления объектов. Смотрите описание ниже.
- ModelAdmin.history_view(request, object_id, extra_context=None)¶
Представление Django для страницы истории изменений объекта модели.
В отличии от методов ModelAdmin описанных выше, которые позволяют изменять поведение интерфейса администратора, эти пять методов используются как представления Django для выполнения 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 интерфейса администратора использует библиотеку jQuery.
Чтобы избежать конфликтов с пользовательскими скриптами или библиотеками, jQuery Django (версия 3.7.1) имеет пространство имен django.jQuery. Если вы хотите использовать jQuery в своем собственном административном JavaScript без включения второй копии, вы можете использовать объект django.jQuery в списке изменений и добавлять/редактировать представления. Кроме того, ваши собственные административные формы или виджеты, зависящие от django.jQuery, должны указывать js=['admin/js/jquery.init.js', …] при объявлении медиа-ресурсов формы <assets-as-a-static-definition>`.
jQuery был обновлен с 3.6.4 до 3.7.1.
Класс ModelAdmin использует jQuery по умолчанию, так что вам не нужно добавлять jQuery в список media-файлов ModelAdmin. Если вам необходима библиотека jQuery в глобальном пространстве имен, например при использовании плагинов jQuery, или более новая версия jQuery, вам необходимо добавить собственную копию jQuery.
Django содержит сжатую и „minified“ версию jQuery, как jquery.js и jquery.min.js соответственно.
ModelAdmin и InlineModelAdmin содержат свойство media, которое возвращает список объектов Media, которые содержат путь к JavaScript файлам для форм и наборов форм. Если DEBUG равна True, будет использована несжатая версия 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, чтобы избежать проблем и ошибок. Подробности смотрите в документации о формах раздел про проверку полей и, особенно, раздел о переопределении метода clean() в ModelForm.
Объект InlineModelAdmin¶
- class InlineModelAdmin¶
- class TabularInline¶
- class StackedInline¶
Интерфейс администратора позволяет редактировать связанные объекты на одной странице с родительским объектом. Это называется «inlines». Например, у нас есть две модели:
from django.db import models class Author(models.Model): name = models.CharField(max_length=100) class Book(models.Model): author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=100)
Вы можете редактировать книги автора на странице редактирования автора. Вы добавляете «inlines» к модели добавив их в
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, вот они:
get_queryset()
Параметры класса InlineModelAdmin:
- InlineModelAdmin.model¶
Модель используемая в «inline». Обязательный параметр.
- InlineModelAdmin.fk_name¶
Название внешнего ключа модели. В большинстве случаев он определяется автоматически, но вы должны указать
fk_name, если модель содержит несколько внешних ключей к родительской модели.
- InlineModelAdmin.formset¶
По умолчанию –
BaseInlineFormSet. Использование собственного класса предоставляет большие возможности для переопределения поведения по умолчанию. Смотрите раздел о наборах модельных форм.
- InlineModelAdmin.form¶
Значение
formпо умолчанию –ModelForm. Это значение передается вinlineformset_factory()при создании набора форм.
Предупреждение
При добавлении собственной валидации в форму InlineModelAdmin, учитывайте состояние родительской модели. Если родительская форма не пройдет валидацию, она может содержать не консистентные данные. Смотрите предупреждение в Валидация в ModelForm.
- InlineModelAdmin.classes¶
Список или кортеж, содержащий дополнительные классы CSS для применения к набору полей, отображаемому для встроенных строк. По умолчанию установлено значение «Нет». Как и в случае с классами, настроенными в
fieldsets, встроенные строки с классомcollapseизначально будут свернуты с использованием расширяемого виджета.Changed in Django 5.1:fieldsets, использующие классcollapse, теперь используют элементы<details>и<summary>, при условии, что они определяютname.
- InlineModelAdmin.extra¶
Это контролирует количество дополнительных форм, которые будет отображаться в наборе форм в дополнение к исходным формам. По умолчанию — 3. Дополнительную информацию см. в документации по наборам форм </topics/forms/formsets>`.
Если JavaScript включен в браузере, ссылка «Add another» позволит добавить новую пустую форму в дополнение к формам указанным параметром
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. Если связанных объектов очень много, создание <select> может быть очень затратным процессом.raw_id_fieldsсодержит список полей, которые будут использовать полеInputдляForeignKeyилиManyToManyField:class BookInline(admin.TabularInline): model = Book raw_id_fields = ["pages"]
- InlineModelAdmin.template¶
Шаблон для отображения.
- InlineModelAdmin.verbose_name¶
Переопределение
verbose_nameиз внутреннего классаMetaмодели.
- InlineModelAdmin.verbose_name_plural¶
Переопределение
verbose_name_pluralиз внутреннего классаMetaмодели. Если это не указано иInlineModelAdmin.verbose_nameопределен, Django будет использоватьInlineModelAdmin.verbose_name+s'.
- InlineModelAdmin.can_delete¶
Определяет можно ли удалять связанные объекты. По умолчанию равно
True.
- InlineModelAdmin.show_change_link¶
Определяет показывать ли ссылку на форму изменения для связанных объектов, которые можно изменять. По умолчанию равно
False.
- InlineModelAdmin.get_formset(request, obj=None, **kwargs)¶
Возвращает
BaseInlineFormSet, который будет использоваться на странице создания/редактирования. Смотрите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.
- InlineModelAdmin.has_change_permission(request, obj=None)¶
Должен возвращать
True, если пользователю позволено добавлять новый объект, иначеFalse.
- InlineModelAdmin.has_delete_permission(request, obj=None)¶
Должен возвращать
True, если пользователю позволено добавлять новый объект, иначеFalse.
Примечание
Аргумент 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"
)
Если вы хотите использовать «inline» для этой модели на странице редактирования/добавления объектов Person, вам необходимо указать какой внешний ключ использовать:
from django.contrib import admin
from myapp.models import Friendship
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
Работа со связями многие-ко-многим¶
По умолчанию виджеты администратора для отношений «многие-ко-многим» будут отображаться в любой модели, содержащей фактическую ссылку на ManyToManyField. В зависимости от вашего определения ModelAdmin каждое поле «многие-ко-многим» в вашей модели будет представлено стандартным HTML-кодом «<select Multiple>», горизонтальным или вертикальным фильтром или виджетом «raw_id_fields». Однако эти виджеты также можно заменить встроенными.
Предположим у нас есть следующие модели:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, related_name="groups")
Необходимо определить объект InlineModelAdmin для связи многое-ко-многим:
from django.contrib import admin
class MembershipInline(admin.TabularInline):
model = Group.members.through
class PersonAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
class GroupAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
exclude = ["members"]
Есть две вещи в этом примере, которые следует отметить.
Первая - класс MembershipInline ссылается на Group.members.through. Атрибут through указывает на модель управляющую связью многое-ко-многим. Эта модель автоматически создается Django при определении связи.
Вторая – класс GroupAdmin должен явно исключить поле members. Django отображает поле для связи многое-ко-многим (в нашем случае с моделью Group). Если вы хотите использовать «inline», необходимо указать Django, что поле не нужно отображать - иначе мы получим два виджета для редактирования связи.
Обратите внимание, при использовании такого подхода сигнал m2m_changed не вызывается. Это вызвано тем, что для админки through просто модель с двумя внешними ключами, а не связь много-ко-многим.
Во всем остальном InlineModelAdmin работает так же, как и всегда. Вы можете управлять отображением используя параметры ModelAdmin.
Работа с промежуточной моделью связи многое-ко-многим¶
Если указать аргумент through для поля ManyToManyField, интерфейс администратора не отобразит поле для редактирования. Это связано с тем, что промежуточная модель требует больше данных, чем позволяет ввести стандартное поле.
Однако, нам необходимо редактировать информацию промежуточной модели. К счастью это можно сделать используя «inline» в интерфейсе администратора. Предположим у нас есть следующие модели:
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, кроме количества дополнительных форм. Вы можете изменить любые параметры класса 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.
Использование связей с несколькими моделями в интерфейсе администратора¶
Вы можете использовать «inline» для связей с несколькими моделями(generic relations). Предположим, у вас есть следующие модели:
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 найдет шаблоны из 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 можно переопределить для приложения или модели. Вот список переопределяемых шаблонов:
app_index.htmlapp_index.htmlchange_form.htmlchange_form.htmlchange_list.htmlchange_list.htmlchange_list.htmlobject_history.htmldelete_confirmation.htmlobject_history.htmlchange_list.htmlapp_index.htmlapp_index.htmlchange_form.htmlapp_index.html
Остальные шаблоны вы можете все еще переопределить для всего проекта. Просто добавьте новую версию шаблона в каталог templates/admin. Это особенно полезно для переопределения страниц для 404 и 500 ошибки.
Примечание
Некоторые шаблоны, такие как change_list_request.html используются для отображения включаемых тегов(inclusion tags). Вы можете переопределить их, но лучше создать собственную версию тега, которая будет использовать новый шаблон. В этом случае вы сможете использовать оба шаблона.
Главный шаблон и шаблон страницы входа¶
Чтобы переопределить шаблоны главной страницы и страниц входа/выхода, лучше создать собственный экземпляр AdminSite (смотрите ниже), и изменить свойства AdminSite.index_template , AdminSite.login_template и AdminSite.logout_template.
Поддержка тем¶
Администратор использует переменные CSS для определения цветов и шрифтов. Это позволяет менять темы без необходимости переопределять множество отдельных правил CSS. Например, если вы предпочитаете фиолетовый цвет вместо синего, вы можете добавить в свой проект переопределение шаблона admin/base.html:
{% extends 'admin/base.html' %}
{% block extrastyle %}{{ block.super }}
<style>
html[data-theme="light"], :root {
--primary: #9774d5;
--secondary: #785cab;
--link-fg: #7c449b;
--link-selected-fg: #8f5bb2;
}
</style>
{% endblock %}
Список переменных CSS определен в django/contrib/admin/static/admin/css/base.css.
Переменные темного режима, соответствующие медиа-запросу prefers-color-scheme, определены в django/contrib/admin/static/admin/css/dark_mode.css. Это связано с документом в {%block dark-mode-vars %}.
Объект AdminSite¶
- class AdminSite(name='admin')¶
Интерфейс администратора Django представлен экземпляром
django.contrib.admin.sites.AdminSite. По умолчанию, экземпляр этого класса находится вdjango.contrib.admin.siteи вы можете зарегистрировать модели с подклассамиModelAdminв нем.Если вы хотите настроить сайт администрирования по умолчанию, вы можете переопределить его.
При создании экземпляра
AdminSite, вы можете указать уникальное название экземпляра приложения передав аргументnameв конструктор. Это название используется для идентификации экземпляра что важно при поиске URL-ов интерфейса администратора. Если этот аргумент не указан, будет использовано значение по умолчаниюadmin. Смотрите раздел Настройка класса AdminSite о том, как настраивать классAdminSite.
- django.contrib.admin.sites.all_sites¶
WeakSetсодержит все экземпляры сайта администрирования.
Атрибуты AdminSite¶
Можно переопределить или заменить основные шаблоны в интерфейсе администратора как это описано в разделе Переопределение шаблонов в интерфейсе администратора.
- AdminSite.site_header¶
Текст, который нужно поместить вверху каждой страницы администрирования, в виде
<div>(строка). По умолчанию это «Администрирование Django».Changed in Django 5.0:В старых версиях site_header использовал тег <h1>.
- AdminSite.site_title¶
Текст, который добавляется в
<title>каждой страницы. По умолчанию «Django site admin».
- AdminSite.site_url¶
URL для ссылки «View site» на верху каждой страницы админки. По умолчанию
site_urlравен/. Чтобы убрать эту ссылку, укажитеNone.Для сайтов, работающих по подпути, метод
each_context()проверяет, установлен ли в текущем запросеrequest.META['SCRIPT_NAME'], и использует это значение, если дляsite_urlне установлено значение, отличное от/.
- AdminSite.index_title¶
Текст, который отображается в верху главной странице админки. По умолчанию «Site administration».
- AdminSite.index_template¶
Шаблон, который будет использоваться для главной страницы.
- AdminSite.app_index_template¶
Шаблон, который будет использоваться для главной страницей приложения.
- AdminSite.empty_value_display¶
Строка, которая используется при отображении пустых значений на странице списка объектов. По умолчанию равна
"-". Значение можно переопределить дляModelAdminи для каждого поляModelAdmin, указав атрибутempty_value_displayдля поля. Примеры смотрите вModelAdmin.empty_value_display.
Логическое значение, определяющее, отображать ли боковую панель навигации на больших экранах. По умолчанию установлено значение «True».
- AdminSite.final_catch_all_view¶
Логическое значение, определяющее, добавлять ли администратору окончательное всеобъемлющее представление, которое перенаправляет неаутентифицированных пользователей на страницу входа. По умолчанию установлено значение «True».
Предупреждение
Устанавливать для этого параметра значение «False» не рекомендуется, так как представление защищает от потенциальной проблемы конфиденциальности перечисления моделей.
- AdminSite.login_template¶
Шаблон, который будет использоваться для страницы входа.
- AdminSite.login_form¶
Подкласс
AuthenticationFormкоторый будет использовать для представления авторизации в интерфейсе администратора.
- AdminSite.logout_template¶
Шаблон, который будет использоваться для страницы выхода.
- AdminSite.password_change_template¶
Шаблон, который будет использоваться для страницы смены пароля.
- AdminSite.password_change_done_template¶
Шаблон, который будет использоваться для страницы завершения смены пароля.
Методы AdminSite¶
- AdminSite.each_context(request)¶
Возвращает словарь переменных, которые будут добавлены в контекст шаблона для каждой странице этой админки.
По умолчанию содержит следующие переменны:
site_header:AdminSite.site_headersite_title:AdminSite.site_titlesite_url:AdminSite.site_urlhas_permission:AdminSite.has_permission()available_apps: список приложений из регистра приложений, которые доступны для текущего пользователя. Каждый элемент списка содержит словарь, который представляет приложение, со следующими ключами:app_label: название приложенияapp_url: URL главное страницы приложения в админкеhas_module_perms: булево, которые указывает есть ли у пользователя права к главной странице приложения в админкеmodels: список моделей прилоджения
Каждая модель представлена словарем со следующими ключами:
модель: класс моделиobject_name: название класса моделиname: множественное название моделиperms:dictсо значениями правadd,changeиdeleteadmin_url: URL к странице списка объектов модели в админкеadd_url: URL к странице добавления объекта модели в админке
is_popup: отображается ли текущая страница во всплывающем окне.is_nav_sidebar_enabled:AdminSite.enable_nav_sidebarlog_entries:AdminSite.get_log_entries()
- AdminSite.get_app_list(request, app_label=None)¶
Возвращает список приложений из реестра приложений, доступных текущему пользователю. При желании вы можете передать аргумент app_label, чтобы получить подробную информацию об одном приложении. Каждая запись в списке представляет собой словарь, представляющий приложение со следующими ключами:
app_label: название приложенияapp_url: URL главное страницы приложения в админкеhas_module_perms: булево, которые указывает есть ли у пользователя права к главной странице приложения в админкеmodels: список моделей прилодженияname: имя приложения
Каждая модель представляет собой словарь со следующими ключами:
модель: класс моделиobject_name: название класса моделиname: множественное название моделиperms:dictсо значениями правadd,changeиdeleteadmin_url: URL к странице списка объектов модели в админкеadd_url: URL к странице добавления объекта модели в админке
Списки приложений и моделей отсортированы в алфавитном порядке по их названиям. Вы можете переопределить этот метод, чтобы изменить порядок по умолчанию на индексной странице администратора.
- AdminSite.has_permission(request)¶
Возвращает
True, если пользователь из переданногоHttpRequestимеет доступ хотя бы к одной странице админки. По умолчанию проверяется равны лиUser.is_activeиUser.is_staffTrue.
- AdminSite.register(model_or_iterable, admin_class=None, **options)¶
Регистрирует данный класс модели (или итерацию классов) с заданным
admin_class.admin_classпо умолчанию имеет значениеModelAdmin(параметры администратора по умолчанию). Если указаны аргументы ключевого слова, напримерlist_display— они будут применены как опции к классу администратора.Вызывает
ImproperlyConfigured, если модель абстрактна. иdjango.contrib.admin.Exceptions.AlreadyRegistered, если модель уже зарегистрирована.
- AdminSite.unregister(model_or_iterable)¶
Отменяет регистрацию данного класса модели (или итерации классов).
Вызывает django.contrib.admin.Exceptions.NotRegistered, если модель еще не зарегистрирована.
- AdminSite.get_model_admin(model)¶
- New in Django 5.0.
Возвращает класс администратора для данного класса модели. Вызывает django.contrib.admin.Exceptions.NotRegistered, если модель не зарегистрирована.
Добавление экземпляра AdminSite в URLconf¶
Последний шаг это добавить ваш экземпляр AdminSite в URLconf. Выполните это добавив в URLconf метод 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. Затем добавьте ваш подкласс AdminSite в myproject/urls.py.
myapp/admin.py¶from 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.py¶from django.urls import path
from myapp.admin import admin_site
urlpatterns = [
path("myadmin/", admin_site.urls),
]
Обратите внимание, при использовании своего экземпляра AdminSite, возможно, вы не захотите отключить автоматический поиск модулей admin и регистрацию их в стандартной админке. Для этого укажите 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin' в настройке INSTALLED_APPS. Скорее всего в этом случае вы будете импортировать модули admin в вашем модуле myproject.admin.
Переопределение шаблонов в интерфейсе администратора¶
Вы можете переопределить значение по умолчанию django.contrib.admin.site, установив атрибут default_site пользовательского AppConfig в пунктирный путь импорта либо подкласса AdminSite, либо вызываемого объекта, который возвращает экземпляр сайта.
myproject/admin.py¶from django.contrib import admin
class MyAdminSite(admin.AdminSite): ...
myproject/apps.py¶from django.contrib.admin.apps import AdminConfig
class MyAdminConfig(AdminConfig):
default_site = "myproject.admin.MyAdminSite"
myproject/settings.py¶INSTALLED_APPS = [
# ...
"myproject.apps.MyAdminConfig", # replaces 'django.contrib.admin'
# ...
]
Несколько интерфейсов администратора в одном URLconf¶
Django позволяет легко создать несколько интерфейсов администратора для одного сайта. Просто создайте несколько экземпляров AdminSite и добавьте его к различным URL-ам.
В этом примере, URL-ы /basic-admin/ и /advanced-admin/ ведут к различным экземплярам AdminSite – myproject.admin.basic_site и myproject.admin.advanced_site соответственно:
# urls.py
from django.urls import path
from myproject.admin import advanced_site, basic_site
urlpatterns = [
path("basic-admin/", basic_site.urls),
path("advanced-admin/", advanced_site.urls),
]
Конструктор AdminSite принимает единственный аргумент – название экземпляра, которое может быть любым. Это значение будет использоваться как префикс для названий URL при их поиске. Это необходимо если вы используете несколько экземпляров AdminSite.
Добавление представлений в интерфейс администратора¶
Как и ModelAdmin AdminSite содержит метод get_urls(), который можно переопределить и добавить собственные представления в интерфейс администратора. Переопределите метод get_urls() и добавьте URL-шаблоны с вашими представлениями.
Примечание
Каждое представление, которое использует шаблоны интерфейса администратора или унаследованные шаблоны, должно указать request.current_app перед рендерингом шаблона. Он должен быть равен self.name, если представление определенно в AdminSite, или self.admin_site.name, если определено в ModelAdmin.
Добавление возможности сброса пароля¶
Вы можете определить возможность сбросить пароль добавив несколько строк в URLconf. А точнее добавьте эти четыре URL-шаблона:
from django.contrib import admin
from django.contrib.auth import views as auth_views
path(
"admin/password_reset/",
auth_views.PasswordResetView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="admin_password_reset",
),
path(
"admin/password_reset/done/",
auth_views.PasswordResetDoneView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="password_reset_done",
),
path(
"reset/<uidb64>/<token>/",
auth_views.PasswordResetConfirmView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="password_reset_confirm",
),
path(
"reset/done/",
auth_views.PasswordResetCompleteView.as_view(
extra_context={"site_header": admin.site.site_header}
),
name="password_reset_complete",
),
(Предполагается что вы уже добавили приложения интерфейса администратора к admin/ и что оно указано после всех URL-шаблонов начинающихся с ^admin/ ).
Наличие URL-шаблона с названием admin_password_reset приведет к появлению ссылки «забыли ваш пароль?» на странице входа в интерфейсе администратора.
Объекты LogEntry¶
- class models.LogEntry¶
Класс
LogEntryследит за добавлением, изменение и удалением объектов, которые выполняются через админку.
Атрибуты LogEntry¶
- LogEntry.action_time¶
Дата и время действия.
- LogEntry.user¶
Пользователь (объект
AUTH_USER_MODEL), который выполнил действие.
- LogEntry.content_type¶
ContentTypeизмененного объекта.
- LogEntry.object_id¶
Текстовое представление первичного ключа измененного объекта.
- LogEntry.object_repr¶
Результат
repr()над объектом после изменения.
- LogEntry.action_flag¶
Тип действия:
ADDITION,CHANGE,DELETION.Например, чтобы получить все добавления через админку:
from django.contrib.admin.models import ADDITION, LogEntry LogEntry.objects.filter(action_flag=ADDITION)
- LogEntry.change_message¶
Подробное описание модификации. Например, в случае редактирования сообщение содержит список отредактированных полей. Сайт администратора Django форматирует это содержимое как структуру JSON, чтобы
get_change_message()мог заново составить сообщение, переведенное на текущий язык пользователя. Однако пользовательский код может установить это как простую строку. Вам рекомендуется использовать методget_change_message()для получения этого значения вместо прямого доступа к нему.
Методы LogEntry¶
- LogEntry.get_edited_object()¶
Возвращает связанный объект.
- LogEntry.get_change_message()¶
Форматирует и переводит
change_messageна текущий язык пользователя. Сообщения, созданные до версии Django 1.10, всегда будут отображаться на том языке, на котором они были зарегистрированы.
Поиск URL-ов интерфейса администратора¶
После установки AdminSite можно указывать ссылки к представлениям интерфейса администратора используя систему поиска URL-ов.
AdminSite предоставляет следующие именованные URL-шаблоны:
Страница |
Название URL-а |
Параметры |
|---|---|---|
Главная |
|
|
Авторизоваться |
|
|
Выхода |
|
|
Смена пароля |
|
|
Завершения смены пароля |
|
|
i18n JavaScript |
|
|
Главная страница приложения |
|
|
Редирект на страницу объекта |
|
|
Каждый экземпляр ModelAdmin предоставляет дополнительные именованные URL-шаблоны:
Страница |
Название URL-а |
Параметры |
|---|---|---|
Список объектов |
|
|
Добавления объекта |
|
|
Истории |
|
|
Удаления объекта |
|
|
Изменения объекта |
|
|
UserAdmin предоставляет следующие именованные URL-шаблоны:
Страница |
Название URL-а |
Параметры |
|---|---|---|
Смена пароля |
|
|
Эти именованные URL-шаблоны зарегистрированы с названием экземпляра приложения admin и названием экземпляра приложения, указанным при создании AdminSite.
Итак, если вы хотите получить ссылку на представление «Изменение» для конкретного объекта «Выбор» (из приложения опросов) в администраторе по умолчанию, вы должны позвонить:
>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse("admin:polls_choice_change", args=(c.id,))
Этот код найдет первый зарегистрированный экземпляр приложения admin (не зависимо от определенного названия экземпляра) и найдет ссылку на представление для редактирования объекта poll.Choice.
Если вы хотите найти URL-адрес в определенном экземпляре администратора, укажите имя этого экземпляра в качестве подсказки «current_app» для обратного вызова. Например, если вы специально хотите получить представление администратора из экземпляра администратора с именем «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, назначенному непосредственно функции. Его нельзя использовать вместе с логическим значением — они взаимоисключающие.Использование этого декоратора не является обязательным для создания функции отображения, но может быть полезно использовать его без аргументов в качестве маркера в исходном коде для определения цели функции:
@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): ...