Одна из сильных сторон Django – это автоматический интерфейс администратора. Он использует мета-данные модели чтобы предоставить многофункциональный, готовый к использованию интерфейс для работы с содержимым сайта. В этом разделе мы расскажем как установить, использовать и настроить интерфейс администратора Django.
Установка интерфейса администратора состоит из семи шагов:
Добавьте 'django.contrib.admin' в настройку INSTALLED_APPS.
Интерфейс администратора имеет четыре зависимости - django.contrib.auth, django.contrib.contenttypes, django.contrib.messages and django.contrib.sessions. Если эти приложения не входят в список INSTALLED_APPS, добавьте их.
Добавьте django.contrib.messages.context_processors.messages в TEMPLATE_CONTEXT_PROCESSORS и MessageMiddleware в MIDDLEWARE_CLASSES. (Эти параметры включены по умолчанию, вам необходимо добавить их только, если вы изменяли эти настройки.)
Определите какие модели будут редактироваться через интерфейс администратора.
Для каждой модели вы можете создать класс ModelAdmin, который инкапсулирует настройки интерфейса администратора для конкретной модели.
Создайте экземпляр AdminSite и добавьте в него ваши модели с соответствующими классами ModelAdmin.
Добавьте AdminSite в URLconf.
После всего это вы можете использовать интерфейс администратора Django посетив соответствующий URL (/admin/ по умолчанию).
См.также
Информацию о настройке статических файлов (изображений, JavaScript и CSS) для интерфейса администратора на “боевом” сервере можно найти в разделе Serving files.
Класс ModelAdmin – это отображение модели в интерфейсе администратора. Его код добавляют в файл admin.py вашего приложения. Давайте рассмотрим простой пример ModelAdmin:
from django.contrib import admin
from myproject.myapp.models import Author
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
Do you need a ModelAdmin object at all?
В этом примере, класс ModelAdmin не определяет никаких настроек (пока).В результате мы получим интерфейс предоставляемый по умолчанию. Если он вас устраивает, вы можете не определять ModelAdmin совсем и зарегистрировать модель без ModelAdmin. Пример выше может выглядеть таким образом:
from django.contrib import admin
from myproject.myapp.models import Author
admin.site.register(Author)
ModelAdmin очень гибкий. Он содержит ряд параметров для настройки интерфейса администратора. Все настройки определяются в подклассе ModelAdmin:
class AuthorAdmin(admin.ModelAdmin):
date_hierarchy = 'pub_date'
Список действий, которые будут включены на странице списка объектов. Подробности смотрите в разделе Admin actions.
Определяет где на странице будет расположены панели с действиями. По умолчанию эта панель расположена сверху (actions_on_top = True; actions_on_bottom = False).
Указывает отображать ли счетчик выбранных объектов. По умолчанию он отображается (actions_selection_counter = True).
Укажите в date_hierarchy название DateField или DateTimeField поля вашей модели, и страница списка объектов будет содержать навигацию по датам из этого поля.
Например:
date_hierarchy = 'pub_date'
Навигация учитывает значения поля, например, если все значения будут датами из одного месяца, будут отображаться только дни этого месяца.
Этот атрибут должен содержать список полей, которые не будут включены в форму редактирования.
Например, у нас есть следующая модель:
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 следующим образом:
class AuthorAdmin(admin.ModelAdmin):
fields = ('name', 'title')
class AuthorAdmin(admin.ModelAdmin):
exclude = ('birth_date',)
Так как модель содержит только три поля, name, title и birth_date, полученные формы будут содержать одинаковые поля.
Если вам необходимо внести небольшие изменения форму на странице редактирования и добавления, например, изменить список отображаемых полей, их порядок или сгруппировать их, вы можете использовать настройку fields (сложные изменения можно выполнить используя настройку fieldsets описанную ниже). Например, необходимо изменить форму модели из приложения django.contrib.flatpages.FlatPage:
class FlatPageAdmin(admin.ModelAdmin):
fields = ('url', 'title', 'content')
В примере выше будут отображаться только поля url, title и content.
fields может содержать значения из ModelAdmin.readonly_fields, чтобы отображать поля без возможности их редактирования.
Что бы поля отображались в одной строке, укажите их в кортеже вместе. В этом примере, поля url и title будут отображаться в одном ряду, поле content будет расположено ниже:
class FlatPageAdmin(admin.ModelAdmin):
fields = (('url', 'title'), 'content')
Note
Настройку fields не следует путать с ключом словаря fields в настройке fieldsets, описанной ниже.
Если не определен ни атрибут fields, ни fieldsets, Django покажет все поля с editable=True кроме AutoField, в одном наборе полей в порядке, в котором они указанные в модели.
Позволяет изменить макет страниц добавления и редактирования объекта.
fieldsets – это список двух-элементных кортежей, каждый представляет <fieldset> в форме редактирования объекта. (<fieldset> – группа полей в форме.)
Кортеж должен быть в формате (name, options полей), где name это название группы полей, а field_options – словарь с информацией о группе полей, включая список полей для отображения.
Полный пример для модели django.contrib.flatpages.FlatPage:
class FlatPageAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': ('url', 'title', 'content', 'sites')
}),
('Advanced options', {
'classes': ('collapse',),
'fields': ('enable_comments', 'registration_required', 'template_name')
}),
)
Этот пример будет выглядеть следующим образом:
Если не определен ни атрибут fields, ни fieldsets, Django покажет все поля с editable=True кроме AutoField, в одном наборе полей в порядке, в котором они указанные в модели.
Словарь field_options может содержать следующие ключи:
Кортеж с названиями полей. Этот ключ обязателен.
Например:
{
'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, чтобы отображать поля без возможности их редактирования.
Список содержащий CSS классы, которые будут добавлены в группу полей.
Например:
{
'classes': ['wide', 'extrapretty'],
}
Django предоставляет два класса для использования: collapse и wide. Группа полей с классом collapse будет показа в свернутом виде с кнопкой “развернуть”. Группа полей с классом wide будет шире по горизонтали.
Необязательный текст, который будет отображаться под названием группы полей.
Заметим, что этот текст не будет экранирован. Это позволяет добавить вам HTML на страницу. Вы можете использовать обычный текст экранировав его функцией django.utils.html.escape().
По умолчанию, поле ManyToManyField отображается как <select multiple>. Однако, это поле тяжело использовать при большом количестве объектов. Добавив ManyToManyField в этот атрибут, будет использоваться “виджет” с JavaScript фильтром для поиска. Смотрите описание filter_vertical про использование вертикального “виджета”.
Аналогичен filter_horizontal, но использует вертикальный “виджет”.
По умолчанию ModelForm создается динамически для модели. Этот атрибут используется для определения формы на страницах добавления и редактирования. Вы можете указать собственный подкласс ModelForm для переопределения этих страниц.
Пример смотрите в разделе `Adding custom validation to the admin`_.
Note
Если и ModelForm и ModelAdmin определяют опцию exclude, ModelAdmin будет иметь больший приоритет:
class PersonForm(forms.ModelForm):
class Meta:
model = Person
exclude = ['name']
class PersonAdmin(admin.ModelAdmin):
exclude = ['age']
form = PersonForm
В этом примере, поле “age” не будет добавлено в форму в отличии от поля “name”.
Позволяет быстро изменить настройки отображения различных типов Field в интерфейсе администратора. formfield_overrides – словарь указывающий параметры для классов полей, которые будут передаваться в конструкторы указанных полей.
Все это звучит немного абстрактно, так что давайте рассмотрим пример. Самое распространенное применение formfield_overrides это переопределить “виджет” поля формы. Предположим у нас есть RichTextEditorWidget, который использует расширенное поля редактирования вместо <textarea>. Вот как мы может использовать его:
from django.db import models
from django.contrib import admin
# Import our custom widget and our model from where they're defined
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel
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 переопределяют виджет.
Возвращает класс Changelist, который используется для отображения списка объекта. По умолчанию, используется django.contrib.admin.views.main.ChangeList. Унаследовав этот класс вы можете переопределить поведение этой страницы.
Смотрите описание ниже InlineModelAdmin.
list_display указывает какие поля отображать на странице списка объектов.
Например:
list_display = ('first_name', 'last_name')
Если list_display не указан, Django отобразить только результат __unicode__() объекта.
Вы можете указать четыре варианта значений в list_display:
Поле модели. Например:
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name')
Функция, которая принимает один аргумент - объект модели. Например:
def upper_case_name(obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
class PersonAdmin(admin.ModelAdmin):
list_display = (upper_case_name,)
Название атрибута ModelAdmin. Работает так же как и функция. Например:
class PersonAdmin(admin.ModelAdmin):
list_display = ('upper_case_name',)
def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
Название атрибута модели. Работает так же как и функция, но self в этом контексте объект модели. Например:
class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField()
def decade_born_in(self):
return self.birthday.strftime('%Y')[:3] + "0's"
decade_born_in.short_description = 'Birth decade'
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'decade_born_in')
Несколько особенностей list_display:
Если указано поле ForeignKey, Django покажет результат __unicode__() связанного объекта.
ManyToManyField не поддерживается, так как это влечет к созданию SQL запроса для каждого объекта. Если вам необходимо сделать это в любом случае, создайте метод модели и используйте его в list_display. (Смотрите ниже подробности про использование методов в list_display.)
Если поле BooleanField или NullBooleanField, Django покажет красивую “on” или “off” иконку вместо True или False.
Если используется метод модели, ModelAdmin или функция, Django по умолчанию экранирует результат. Если вам не нужно экранировать результат, добавьте атрибут allow_tags методу или функции со значением True.
Пример:
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)
def colored_name(self):
return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
colored_name.allow_tags = True
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'colored_name')
Если используется метод модели, ModelAdmin или функция, которая возвращает True или False, Django покажет “on” или “off” иконки, если вы добавите атрибут boolean методу или функции со значением True.
Пример:
class Person(models.Model):
first_name = models.CharField(max_length=50)
birthday = models.DateField()
def born_in_fifties(self):
return self.birthday.strftime('%Y')[:3] == '195'
born_in_fifties.boolean = True
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'born_in_fifties')
Вы можете использовать методы __str__() и ``__unicode__()`:
list_display = ('__unicode__', 'some_other_field')
Обычно элементы list_display, которые не являются полями модели, не могу быть использованы при сортировке (так как Django выполняет сортировку на уровне базы данных).
Однако, если элемент list_display представляет определенное поле в базе данных, вы можете указать это добавив атрибут admin_order_field к элементу.
Например:
class Person(models.Model):
first_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
def colored_first_name(self):
return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
colored_first_name.allow_tags = True
colored_first_name.admin_order_field = 'first_name'
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'colored_first_name')
В этом примере Django будет использовать поле first_name при сортировке по colored_first_name.
Используйте list_display_links что бы указать какие поля в list_display будут ссылками на страницу редактирования объекта.
По умолчанию, на страницу редактирования объекта будет вести ссылка в первой колонке. Но list_display_links позволяет изменить это поведение. Установите list_display_links в список или кортеж полей (аналогично list_display).
list_display_links может указывать одно или несколько полей. Пока указанные поля входят в 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')
Укажите в list_editable список полей, которые можно будет редактировать на странице списка объектов. То есть, поля из list_editable будут отображаться как поля формы позволяя пользователям изменять значения и сохранять изменения для всех строк сразу.
Примечание
list_editable взаимодействует с другими настройками следующим образом:
Поле из list_editable должно входить в list_display. Вы мне можете редактировать поле, которое не отображается!
Поле не может быть в list_editable и list_display_links вместе – поле не может быть ссылкой и полем формы.
Вы получите ошибку проверки если нарушите эти правила.
Укажите list_filter что бы определить фильтры данных в правой панели страницы списка объектов, как показано на изображении:
list_filter - это список элементов, которые могу быть:
название поля следующего типа: BooleanField, CharField, DateField, DateTimeField, IntegerField, ForeignKey или ManyToManyField. Например:
class PersonAdmin(ModelAdmin):
list_filter = ('is_staff', 'company')
Поле в list_filter может указывать и на связанный объект используя __, например:
class PersonAdmin(UserAdmin):
list_filter = ('company__name',)
подкласс django.contrib.admin.SimpleListFilter, в котором необходимо определить атрибуты title и parameter_name и переопределить методы lookups и queryset, например:
from datetime import date
from django.utils.translation import ugettext_lazy as _
from django.contrib.admin import SimpleListFilter
class DecadeBornListFilter(SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = _('decade born')
# Parameter for the filter that will be used in the URL query.
parameter_name = 'decade'
def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return (
('80s', _('in the eighties')),
('90s', _('in the nineties')),
)
def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
# Compare the requested value (either '80s' or 'other')
# to decide how to filter the queryset.
if self.value() == '80s':
return queryset.filter(birthday__gte=date(1980, 1, 1),
birthday__lte=date(1989, 12, 31))
if self.value() == '90s':
return queryset.filter(birthday__gte=date(1990, 1, 1),
birthday__lte=date(1999, 12, 31))
class PersonAdmin(ModelAdmin):
list_filter = (DecadeBornListFilter,)
Примечание
Для удобства объект HttpRequest передается в методы lookups и queryset, например:
class AuthDecadeBornListFilter(DecadeBornListFilter):
def lookups(self, request, model_admin):
if request.user.is_superuser:
return super(AuthDecadeBornListFilter,
self).lookups(request, model_admin)
def queryset(self, request, queryset):
if request.user.is_superuser:
return super(AuthDecadeBornListFilter,
self).queryset(request, queryset)
Так же объект ModelAdmin передается в метод lookups. Например, вы можете использовать существующие данные при создании фильтра:
class AdvancedDecadeBornListFilter(DecadeBornListFilter):
def lookups(self, request, model_admin):
"""
Only show the lookups if there actually is
anyone born in the corresponding decades.
"""
qs = model_admin.queryset(request)
if qs.filter(birthday__gte=date(1980, 1, 1),
birthday__lte=date(1989, 12, 31)).exists():
yield ('80s', _('in the eighties'))
if qs.filter(birthday__gte=date(1990, 1, 1),
birthday__lte=date(1999, 12, 31)).exists():
yield ('90s', _('in the nineties'))
кортеж, где первый элемент название поля, а второй - подкласс django.contrib.admin.FieldListFilter, например:
from django.contrib.admin import BooleanFieldListFilter
class PersonAdmin(ModelAdmin):
list_filter = (
('is_staff', BooleanFieldListFilter),
)
Примечание
API FieldListFilter считается внутренним и может быть изменено.
Вы можете указать собственный шаблон для отображения фильтра:
class FilterWithCustomTemplate(SimpleListFilter):
template = "custom_template.html"
Конкретный пример можно найти в шаблоне приложения интерфейса администратора, который использует Django (admin/filter.html).
Используйте list_max_show_all что бы указать количество объектов на странице списка объектов при выборе “Показать все”. Интерфейс администратора покажет ссылку “Показать все” только если общее количество объектов меньше или равно этому значению. По умолчанию равно 200.
Используйте list_per_page что бы определить количество объектов на одной странице при отображении списка объектов. По умолчанию равно 100.
Используйте list_select_related что бы указать Django использовать select_related() при выборе объектов для страницы отображения объектов. Это может сократить количество запросов на этой странице.
Значение должно быть True или False. По умолчанию равно False.
Заметим, Django будет использовать select_related() не зависимо от этой настройки, если хотя бы одно поле в list_display является ForeignKey.
ordering позволяет определить сортировку на странице списка объектов. Это должен быть список или кортеж в формате аналогичном параметру ordering.
Если атрибут не указана, Django будет использовать сортировку по умолчанию модели.
Если вам необходима динамическая сортировка (например, в зависимости от пользователя или текущего языка) вы можете определить метод get_ordering().
Django учитывает все элементы в списке/кортеже, до 1.4 использовался только первый.
Класс используемый для создания постраничного отображения. По умолчанию используется django.core.paginator.Paginator. Если конструктор вашего класса принимает параметры отличные от django.core.paginator.Paginator, вам необходимо так же переопределить метод ModelAdmin.get_paginator().
prepopulated_fields позволяет определить поля, которые получают значение основываясь на значениях других полей:
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
Указанные поля будут использовать код JavaScript для заполнения поля значением на основе значений полей-источников. Основное применение - это генерировать значение для полей SlugField из значений другого поля или полей. Процесс генерирования состоит в объединении значений полей-источников и преобразованию результата в правильный “slug” (например, заменой пробелов на дефисы).
prepopulated_fields не принимает поля DateTimeField, ForeignKey или ManyToManyField.
По умолчанию 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.
По умолчанию Django использует <select> для полей ForeignKey. Если связанных объектов очень много, создание <select> может быть очень затратным процессом.
raw_id_fields содержит список полей, которые будут использовать поле Input для ForeignKey или ManyToManyField:
class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)
По умолчанию интерфейс администратора отображает все поля как редактируемые. Поля указанные в этой настройке (которая является list или tuple) будут отображаться значение без возможности редактировать. Эта настройка работает почти аналогично ModelAdmin.list_display. Однако, если вы определяете аргумент ModelAdmin.fields или ModelAdmin.fieldsets поля для чтения должны быть в них указаны (иначе они будут проигнорированы).
Если readonly_fields используется без определения порядка полей через атрибуты ModelAdmin.fields или ModelAdmin.fieldsets, поля из этой настройки будут отображаться после редактируемых полей.
Укажите save_as что бы включить возможность “сохранять как” на странице редактирования объекта.
По умолчанию страница содержит три кнопки: “Сохранить”, “Сохранить и продолжить редактирование” и “Сохранить и добавить новый”. Если save_as равен True, “Сохранить и добавить новый” будет заменена кнопкой “Сохранить как”.
“Сохранить как” сохранит объект как новый (с новым ID).
По умолчанию save_as равен False.
Укажите save_on_top что бы добавить кнопки сохранения в верхней части страницы редактирования объекта.
По умолчанию кнопки сохранения отображаются под формой. Если указать save_on_top, кнопки будут отображаться и сверху и снизу.
По умолчанию save_on_top равен False.
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%')
Для определения более конкретных условий поиска используйте следующие префиксы:
Указывает на начало строки. Например, если 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%', так как база данных будет проверять только начало значения поля. К тому же, если поле содержит индекс, некоторые базы данных могут использовать его при поиске, даже для поиска через LIKE.
Полное совпадение, регистро-независимое. Например, если 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')
Поисковый запрос разбивается по пробелам, по этому, исходя из примера выше, нельзя найти записи с полем first_name равным ``‘john winston’``(содержащим пробел).
Выполняет полнотекстовый поиск. Работает как и обычный поиск, но использует индекс. На данный момент это работает только в MySQL.
Раздел `Overriding Admin Templates`_ описывает как переопределить или расширить шаблоны интерфейса администратора. Используйте следующие настройки что бы переопределить шаблоны, которые используются представлениями ModelAdmin:
Путь к шаблону, который используется add_view().
Путь к шаблону, который используется change_view().
Путь к шаблону, который используется changelist_view().
Путь к шаблону, который используется delete_view() для отображения страницы подтверждения удаления одного или нескольких объектов.
Путь к шаблону, который используется delete_selected() для отображения страницы подтверждения удаления одного или нескольких объектов. Подробности смотрите в разделе о действиях в интерфейсе администратора.
Путь к шаблону, который используется history_view().
Предупреждение
Методы ModelAdmin.save_model() и ModelAdmin.delete_model() должны сохранять/удалять объект. Их задача выполнять дополнительные операции, а не разрешать/запрещать операции удаления/сохранения.
Метод save_model принимает объект HttpRequest, экземпляр модели, экземпляр ModelForm и булево значение указывающее создан объект или изменяется. В этом методе вы может выполнить дополнительные операции до или после сохранения.
Например, добавление request.user к объекту перед сохранением объекта:
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
Метод delete_model принимает объект HttpRequest и экземпляр модели, который удаляется. В этом методе вы может выполнить дополнительные операции до или после удаления.
Метод save_formset принимает объект HttpRequest, ModelForm родительского объекта, “formset” связанных объектов и булево значение указывающее создан родительский объект или изменяется.
Например, добавление request.user к каждому объекту измененному в “formset”:
class ArticleAdmin(admin.ModelAdmin):
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for instance in instances:
instance.user = request.user
instance.save()
formset.save_m2m()
Метод get_ordering принимает объект request и должен вернуть list или tuple с параметрами сортировки аналогично атрибуту ordering. Например:
class PersonAdmin(ModelAdmin):
def get_ordering(self, request):
if request.user.is_superuser:
return ['name', 'rank']
else:
return ['name']
Метод save_related принимает объект HttpRequest, родительскую форму ModelForm, список “inline formsets” и булево значение указывающее создан родительский объект или изменяется. Вы можете выполнить дополнительные операции перед и после сохранения объектов. Заметим, что к этому моменту родительский объект и его формы уже будут сохранены.
Метод get_readonly_fields принимает объект HttpRequest и редактируемый объект obj (или None для формы создания нового объекта) и должен вернуть list или tuple содержащий список полей, которые будут отображаться только для чтения как описано в разделе ModelAdmin.readonly_fields.
Метод get_prepopulated_fields принимает объект HttpRequest и редактируемый объект obj (или None для формы создания нового объекта) и должен вернуть словарь полей аналогичный ModelAdmin.prepopulated_fields.
Метод get_list_display принимает объект HttpRequest и редактируемый объект obj (или None для формы создания нового объекта) и должен вернуть list или tuple содержащий список полей, которые будут отображаться на странице списка объектов как описано в разделе ModelAdmin.list_display.
Метод get_list_display_links принимает объект HttpRequest и list или tuple указанный в ModelAdmin.get_list_display(). Должен вернуть list или tuple содержащий список полей, который будут ссылками на странице списка объектов к странице редактирования. Смотрите описание ModelAdmin.list_display_links.
Метод get_urls класса ModelAdmin возвращает URL-ы, которые используются для ModelAdmin в URLconf. Вы можете дополнить их как описано в Менеджер URL-ов:
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
my_urls = patterns('',
(r'^my_view/$', self.my_view)
)
return my_urls + urls
def my_view(self, request):
# custom view which should return an HttpResponse
pass
Примечание
Заметим, что собственные URL-шаблоны включаются перед URL-шаблонами интерфейса администратора, которые удовлетворяют почти всем URL-ам. По этому желательно добавлять собственные URL-шаблоны перед встроенными.
В этом примере, представление my_view будет доступно по ссылке /admin/myapp/mymodel/my_view/ (предполагается что вы добавили URL-ы интерфейса администратора к /admin/.)
Однако, есть несколько проблем связанных с функцией self.my_view:
Не выполняются никакие проверки прав, каждый может выполнить запрос к этому представлению.
Не отправляются заголовки управляющие кэшированием. Это означает, если включен кэширующий функциональный слой, данные из базы данных на странице могут быть неверными.
Django предоставляет функцию-обертку для проверки прав и отключения кэширования. Эта функция – AdminSite.admin_view() (или self.admin_site.admin_view в методе ModelAdmin). Используйте ее следующим образом:
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
my_urls = patterns('',
(r'^my_view/$', self.admin_site.admin_view(self.my_view))
)
return my_urls + urls
Обратите внимание на следующую строку:
(r'^my_view/$', self.admin_site.admin_view(self.my_view))
Функция-обертка защищает self.my_view от несанкционированного доступа и применяет декоратор django.views.decorators.cache.never_cache для предотвращения кэширования.
Если страницу необходимо кэшировать, но необходимо проверять авторизацию, вы можете использовать аргумент cacheable=True для AdminSite.admin_view():
(r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True))
Метод 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(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Объект HttpRequest используется что бы отфильтровать для выбора объекты модели Car по текущему пользователю.
Как и метод 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(MyModelAdmin, self).formfield_for_manytomany(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'] += (('ready', 'Ready for deployment'),)
return super(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
Должен возвращать True, если пользователю позволено добавлять новый объект, иначе False.
Должен возвращать True, если пользователю позволено изменять объект, иначе False. Если obj равен None, должен вернуть True или False, указывая может ли пользователь изменить какой-либо объект данного типа.
Должен вернуть True, если пользователю позволено удалять объект, иначе False. Если obj равен None, должен вернуть True или False, указывая может ли пользователь удалить какой-либо объект данного типа.
Метод должен вернуть QuerySet всех объектов модели, которые можно редактировать в интерфейсе администратора. Этот метод можно использовать для отображения объектов принадлежащих текущему пользователю:
class MyModelAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = super(MyModelAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
Отправляет сообщение пользователю. Реализация по умолчанию использует django.contrib.messages для отправки сообщений. Смотрите пример переопределения ModelAdmin.
Возвращает объект для постраничного отображения. По умолчанию возвращает объект paginator.
Представление Django для страницы добавления объекта модели. Смотрите описание ниже.
Представление Django для страницы редактирования объекта модели. Смотрите описание ниже.
Представление Django для страницы отображения всех объектов модели. Смотрите описание ниже.
Представление Django для страницы подтверждения удаления объектов. Смотрите описание ниже.
Представление 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, extra_context=None):
extra_context = extra_context or {}
extra_context['osm_data'] = self.get_osm_info()
return super(MyModelAdmin, self).change_view(request, object_id,
extra_context=extra_context)
Эти методы теперь возвращают объект TemplateResponse, что позволяет легко изменить данные ответа перед выполнением шаблона. Подробности смотрите в разделе о TemplateResponse.
В некоторых ситуациях вам может понадобиться добавить 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) к указанным путям. Это же правильно применяется и к определению статических файлов для форм.
Интерфейс администратора Django использует Javascript библиотеку jQuery. Что бы избежать конфликтов с библиотеками пользователя, jQuery в Django используется пространство имен django.jQuery. Если вы хотите использовать jQuery в собственных JavaScript файлах без добавления еще одной копии, вы можете использовать объект django.jQuery на страницах списка объектов и добавления/редактирования.
Если вам необходима библиотека jQuery в глобальном пространстве имен, например при использовании плагинов jQuery, или более новая версия jQuery, вам необходимо добавить собственную копию jQuery.
Добавить дополнительную проверку данных в интерфейсе администратора очень легко. Интерфейс администратора использует django.forms, и класс ModelAdmin позволяет указать вашу собственную форму:
class ArticleAdmin(admin.ModelAdmin):
form = MyArticleAdminForm
Вы можете определить форму MyArticleAdminForm где угодно, просто импортируйте ее. В собственной форме вы можете добавить дополнительную проверку данных для любого поля:
class MyArticleAdminForm(forms.ModelForm):
class Meta:
model = Article
def clean_name(self):
# do something that validates your data
return self.cleaned_data["name"]
Важно использовать ModelForm что бы избежать проблем и ошибок. Подробности смотрите в документации о формах раздел про проверку полей и, особенно, раздел о переопределении метода clean() в ModelForm.
Интерфейс администратора позволяет редактировать связанные объекты на одной странице с родительским объектом. Это называется “inlines”. Например, у нас есть две модели:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
Вы можете редактировать книги автора на странице редактирования автора. Вы добавляете “inlines” к модели добавив их в ModelAdmin.inlines:
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
Django предоставляет два подкласса InlineModelAdmin:
Разница между ними только в используемом шаблоне.
InlineModelAdmin содержит некоторые возможности ModelAdmin и собственные. Общие методы и атрибуты определены в классе BaseModelAdmin, вот они:
Параметры класса InlineModelAdmin:
Модель используемая в “inline”. Обязательный параметр.
Название внешнего ключа модели. В большинстве случаев он определяется автоматически, но вы должны указать fk_name, если модель содержит несколько внешних ключей к родительской модели.
По умолчанию – BaseInlineFormSet. Использование собственного класса предоставляет большие возможности для переопределения поведения по умолчанию. Смотрите раздел о наборах модельных форм.
Значение по умолчанию – ModelForm. Это значение передается в inlineformset_factory при создании набора форм.
Указывает количество пустых форм для добавления объектов в наборе форм. Подробности смотрите в разделе о наборе форм.
Если JavaScript включен в браузере, ссылка “Add another” позволит добавить новую пустую форму в дополнение к формам указанным параметром extra.
Ссылка не появится если количество отображаемых форм превышает значение в параметре max_num, или если у пользователя отключен JavaScript.
Указывает максимальное количество форм. Этот параметр не определяет количество связанных объектов. Подробности смотрите в разделе Ограничение количества редактируемых объектов.
По умолчанию Django использует <select> для полей ForeignKey. Если связанных объектов очень много, создание <select> может быть очень затратным процессом.
raw_id_fields – список полей которые должны использовать Input виджет для полей ForeignKey или ManyToManyField:
class BookInline(admin.TabularInline):
model = Book
raw_id_fields = ("pages",)
Шаблон для отображения.
Позволяет переопределить значение verbose_name класса Meta модели.
Позволяет переопределить значение verbose_name_plural класса Meta модели.
Определяет можно ли удалять связанные объекты. По умолчанию равно True.
Модель может содержать несколько внешних ключей к одной модели, например:
class Friendship(models.Model):
to_person = models.ForeignKey(Person, related_name="friends")
from_person = models.ForeignKey(Person, related_name="from_friends")
Если вы хотите использовать “inline” для этой модели на странице редактирования/добавления объектов Person, вам необходимо указать какой внешний ключ использовать:
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
По умолчанию, для полей ManyToManyField используется виджет определенный интерфейсом администратора. В зависимости от параметров ModelAdmin``может использоваться стандартное HTML поле ``<select multiple>, горизонтальный или вертикальный фильтр, или виджет raw_id_admin. Однако вместо этого можно использовать “inline”.
Предположим у нас есть следующие модели:
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 для связи многое-ко-многим:
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, что поле не нужно отображать - иначе мы получим два виджета для редактирования связи.
Во всем остальном InlineModelAdmin работает так же как и всегда. Вы можете управлять отображением используя параметры ModelAdmin.
Если указать аргумент through для поля ManyToManyField, интерфейс администратора не отобразит поле для редактирования. Это связано с тем, что промежуточная модель требует больше данных, чем позволяет ввести стандартное поле.
Однако, нам необходимо редактировать информацию промежуточной модели. К счастью это можно сделать используя “inline” в интерфейсе администратора. Предположим у нас есть следующие модели:
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)
group = models.ForeignKey(Group)
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). Предположим у вас есть следующие модели:
class Image(models.Model):
image = models.ImageField(upload_to="images")
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey("content_type", "object_id")
class Product(models.Model):
name = models.CharField(max_length=100)
Если вы хотите редактировать и добавлять объекты Image на странице добавления/редактирования объектов Product, вы можете использовать GenericTabularInline или GenericStackedInline (подклассы GenericInlineModelAdmin) из модуля django.contrib.contenttypes.generic. Они отображают группы форм для добавления и редактирования связанных объектов, как и аналогичные классы из приложения интерфейса администратора. Пример admin.py для наших моделей:
from django.contrib import admin
from django.contrib.contenttypes import generic
from myproject.myapp.models import Image, Product
class ImageInline(generic.GenericTabularInline):
model = Image
class ProductAdmin(admin.ModelAdmin):
inlines = [
ImageInline,
]
admin.site.register(Product, ProductAdmin)
Подробности смотрите в разделе о contenttypes.
Переопределить шаблоны, которые использует интерфейс администратора, очень легко. Вы можете переопределить шаблон для конкретного приложения или модели.
Шаблоны интерфейса администратора находятся в каталоге contrib/admin/templates/admin.
Что бы переопределить их, создайте каталог admin в каталоге templates вашего проекта. Это может любой другой каталог указанный в настройке TEMPLATE_DIRS.
В каталоге 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. Вот наш новый шаблон change_form.html :
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
<li><a href="history/" class="historylink">{% trans "History" %}</a></li>
<li><a href="mylink/" class="historylink">My Link</a></li>
{% if has_absolute_url %}
<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
{% trans "View on site" %}</a>
</li>
{% endif%}
</ul>
{% endif %}{% endif %}
{% endblock %}
Вот и все! Добавим шаблон в каталог templates/admin/my_app и ссылка появится на странице редактирования объекта.
Не каждый шаблон в contrib/admin/templates/admin можно переопределить для приложения или модели. Вот список переопределяемых шаблонов:
Остальные шаблоны вы можете все еще переопределить для всего проекта. Просто добавьте новую версию шаблона в каталог templates/admin. Это особенно полезно для переопределения страниц для 404 и 500 ошибки.
Примечание
Некоторые шаблоны, такие как change_list_request.html используются для отображения включаемых тегов(inclusion tags). Вы можете переопределить их, но лучше создать собственную версию тега, которая будет использовать новый шаблон. В этом случае вы сможете использовать оба шаблона.
Что бы переопределить шаблоны главной страницы и страниц входа/выхода, лучше создать собственный экземпляр ``AdminSite``(смотрите ниже), и изменить свойства AdminSite.index_template , AdminSite.login_template и AdminSite.logout_template.
Интерфейс администратора Django представлен экземпляром django.contrib.admin.sites.AdminSite. По умолчанию, экземпляр этого класса находится в django.contrib.admin.site и вы можете зарегистрировать модели с подклассами ModelAdmin в нем.
Если вам необходимо изменить поведение интерфейса администратора, вы можете создать подкласс AdminSite и переопределить все что вам нужно. Затем создайте экземпляр вашего подкласса AdminSite (как и любого другого класса Python), и зарегистрируйте в нем ваши модели.
При создании экземпляра AdminSite, вы можете указать уникальное название экземпляра приложения передав аргумент name в конструктор. Это название используется для идентификации экземпляра что важно при поиске URL-ов интерфейса администратора. Если этот аргумент не указан, будет использовано значение по умолчанию admin.
Можно переопределить или заменить основные шаблоны в интерфейсе администратора как это описано в разделе `Overriding Admin Templates`_.
Шаблон, который будет использоваться для главной страницы.
Шаблон, который будет использоваться для страницы входа.
Подкласс AuthenticationForm который будет использовать для представления авторизации в интерфейсе администратора.
Шаблон, который будет использоваться для страницы выхода.
Шаблон, который будет использоваться для страницы смены пароля.
Шаблон, который будет использоваться для страницы завершения смены пароля.
Последний шаг это добавить ваш экземпляр AdminSite в URLconf. Выполните это добавив в URLconf свойство AdminSite.urls.
В этом примере мы добавляем экземпляр по умолчанию AdminSite, который находится в django.contrib.admin.site, для URL /admin/
# urls.py
from django.conf.urls import patterns, url, include
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
)
Перед этим мы используем admin.autodiscover() для загрузки модулей admin.py для приложений в INSTALLED_APPS.
В этом примере мы добавляем собственный экземпляр AdminSite, который находится в myproject.admin.admin_site для URL /myadmin/
# urls.py
from django.conf.urls import patterns, url, include
from myproject.admin import admin_site
urlpatterns = patterns('',
(r'^myadmin/', include(admin_site.urls)),
)
Нет необходимости использовать autodiscover если вы импортируете все модули admin.py в myproject.admin для регистрации моделей.
Django позволяет легко создать несколько интерфейсов администратора для одного сайта. Просто создайте несколько экземпляров AdminSite и добавьте его к различным URL-ам.
В этом примере, URL-ы /basic-admin/ и /advanced-admin/ ведут к различным экземплярам AdminSite – myproject.admin.basic_site и myproject.admin.advanced_site соответственно:
# urls.py
from django.conf.urls import patterns, url, include
from myproject.admin import basic_site, advanced_site
urlpatterns = patterns('',
(r'^basic-admin/', include(basic_site.urls)),
(r'^advanced-admin/', include(advanced_site.urls)),
)
Конструктор AdminSite принимает единственный аргумент – название экземпляра, которое может быть любым. Это значение будет использоваться как префикс для названий URL при их поиске. Это необходимо если вы используете несколько экземпляров AdminSite.
Как и ModelAdmin AdminSite содержит метод get_urls(), который можно переопределить и добавить собственные представления в интерфейс администратора. Переопределите метод get_urls() и добавьте URL-шаблоны с вашими представлениями.
Примечание
Каждое представление, которое использует шаблоны интерфейса администратора или унаследованные шаблоны, должно указать аргумент current_app для конструктора RequestContext или Context при выполнении шаблона. Он должен быть равен self.name, если представление определенно в AdminSite, или self.admin_site.name, если определено в ModelAdmin.
Вы можете определить возможно сбросить пароль добавив несколько строк в URLconf. А точнее добавьте эти четыре URL-шаблона:
url(r'^admin/password_reset/$', 'django.contrib.auth.views.password_reset', name='admin_password_reset'),
(r'^admin/password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
(r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
(r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
(Предполагается что вы уже добавили приложения интерфейса администратора к admin/ и что оно указано после всех URL-шаблонов начинающихся с ^admin/ ).
Наличие URL-шаблона с названием admin_password_reset приведет к появлению ссылки “забыли ваш пароль?” на странице входа в интерфейсе администратора.
После установки AdminSite можно указывать ссылки к представлениям интерфейса администратора используя систему поиска URL-ов.
AdminSite предоставляет следующие именованные URL-шаблоны:
Страница |
Название URL-а |
Параметры |
---|---|---|
Главная |
index | |
Выхода |
logout | |
Смена пароля |
password_change | |
Завершения смены пароля |
password_change_done | |
i18n javascript | jsi18n | |
Главная страница приложения |
app_list | app_label |
Каждый экземпляр ModelAdmin предоставляет дополнительные именованные URL-шаблоны:
Страница |
Название URL-а |
Параметры |
---|---|---|
Список объектов |
{{ app_label }}_{{ model_name }}_changelist | |
Добавления объекта |
{{ app_label }}_{{ model_name }}_add | |
Истории |
{{ app_label }}_{{ model_name }}_history | object_id |
Удаления объекта |
{{ app_label }}_{{ model_name }}_delete | object_id |
Изменения объекта |
{{ app_label }}_{{ model_name }}_change | object_id |
Эти именованные URL-шаблоны зарегистрированы с названием экземпляра приложения admin и названием экземпляра приложения, указанным при создании AdminSite.
Например, нам необходимо получить ссылку на страницу изменения объекта модели Choice (из приложения polls) в стандартном интерфейсе администратора. Для этого необходимо выполнить следующий код:
>>> from django.core import urlresolvers
>>> c = Choice.objects.get(...)
>>> change_url = urlresolvers.reverse('admin:polls_choice_change', args=(c.id,))
Этот код найдет первый зарегистрированный экземпляр приложения admin``(не зависимо от определенного названия экземпляра) и найдет ссылку на представление для редактирования объекта ``poll.Choice.
Если необходимо найти URL в определенном экземпляре приложения, укажите значение current_app. Например, если необходимо получить ссылку на представление в экземпляре приложения с названием custom, выполните следующий код:
>>> change_url = urlresolvers.reverse('custom:polls_choice_change', args=(c.id,))
Подробности смотрите в разделе о пространстве имен в конфигурации URL-ов.
Для более удобного поиска URL-ов в шаблонах, Django предоставляет фильтр admin_urlname, который принимает название действия в качестве аргумента:
{% load admin_urls %}
{% load url from future %}
<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 и module_name, эта переменная обычно указывается представлением в интерфейсе администратора для текущей модели.
Mar 30, 2016