Spec-Zone.ru › Django 2.0

Сайт администрирования Django

Одна из самых мощных частей Django — автоматический интерфейс администрирования. Он считывает метаданные из ваших моделей, чтобы предоставить быстрый, ориентированный на модели интерфейс, где авторизованные пользователи могут управлять контентом на вашем сайте. Рекомендуемое использование администрирования ограничено внутренним инструментом управления организации. Он не предназначен для построения всего вашего фронтенда вокруг него.

Администрирование имеет много хуков для настройки, но будьте осторожны, пытаясь использовать эти хуки исключительно. Если вам нужно предоставить более ориентированный на процессы интерфейс, который абстрагирует детали реализации таблиц и полей базы данных, то, вероятно, пришло время написать свои собственные представления.

В этом документе мы обсудим, как активировать, использовать и настраивать интерфейс администрирования Django.

Обзор

Администрирование включено в шаблон проекта по умолчанию, используемый startproject.

Для справки, вот требования:

  1. Добавьте 'django.contrib.admin' в ваше значение INSTALLED_APPS.
  2. Администрирование имеет четыре зависимости — django.contrib.auth, django.contrib.contenttypes, django.contrib.messages и django.contrib.sessions. Если эти приложения отсутствуют в вашем списке INSTALLED_APPS, добавьте их.
  3. Добавьте django.contrib.auth.context_processors.auth и django.contrib.messages.context_processors.messages к параметру 'context_processors' бэкенда, определённого в вашем TEMPLATES, а также django.contrib.auth.middleware.AuthenticationMiddleware и django.contrib.messages.middleware.MessageMiddleware к MIDDLEWARE. Все они активны по умолчанию, поэтому вам нужно это сделать только если вы вручную изменили настройки.
  4. Определите, модели каких приложений должны быть доступны для редактирования в интерфейсе администрирования.
  5. Для каждой из этих моделей необязательно создать класс ModelAdmin, который обобщает настраиваемые функции администрирования и параметры для этой конкретной модели.
  6. Создайте экземпляр AdminSite и сообщите ему о каждой из ваших моделей и классах ModelAdmin.
  7. Подключите экземпляр AdminSite к вашей URLconf.

После выполнения этих шагов вы сможете использовать сайт администрирования Django, перейдя по URL, к которому вы его подключили (/admin/ по умолчанию). Если вам нужно создать пользователя для входа, вы можете использовать команду createsuperuser.

Другие темы

  • Действия администрирования
  • Генератор документации Django admin
  • Настройка JavaScript в администрировании

См. также

Дополнительную информацию об обслуживании статических файлов (изображения, JavaScript и CSS), связанных с администрированием в рабочей среде, см. в разделе Обслуживание файлов.

Возникли проблемы? Обратитесь к FAQ: Администрирование.

ModelAdmin объекты

class ModelAdmin [source]

Класс 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)

Нужен ли вам объект ModelAdmin вообще?

В предыдущем примере класс ModelAdmin не определяет никаких пользовательских значений (ещё). В результате будет предоставлен стандартный интерфейс администрирования. Если вас устраивает стандартный интерфейс администрирования, вам вообще не нужно определять объект ModelAdmin — вы можете зарегистрировать класс модели без предоставления описания ModelAdmin. Представленный пример можно упростить до:

from django.contrib import admin
from myproject.myapp.models import Author

admin.site.register(Author)

Декоратор register

register(*models, site=django.admin.sites.site) [source]

Также существует декоратор для регистрации ваших классов ModelAdmin:

from django.contrib import admin
from .models import Author

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    pass

Ему передаётся одна или несколько моделей для регистрации в ModelAdmin. Если вы используете пользовательский AdminSite, передайте его с помощью ключевого аргумента site:

from django.contrib import admin
from .models import Author, Editor, Reader
from myproject.admin_site import custom_admin_site

@admin.register(Author, Reader, Editor, site=custom_admin_site)
class PersonAdmin(admin.ModelAdmin):
    pass

Вы не можете использовать этот декоратор, если вам нужно обратиться к вашему классу модели администратора в его методе __init__(), например super(PersonAdmin, self).__init__(*args, **kwargs). Вы можете использовать super().__init__(*args, **kwargs).

Обнаружение файлов администратора

Когда вы помещаете 'django.contrib.admin' в ваше значение INSTALLED_APPS, Django автоматически ищет модуль admin в каждом приложении и импортирует его.

class apps.AdminConfig

Это по умолчанию класс AppConfig для администрирования. Он вызывает autodiscover() при запуске Django.

class apps.SimpleAdminConfig

Этот класс работает как AdminConfig, за исключением того, что он не вызывает autodiscover().

autodiscover() [source]

Эта функция пытается импортировать модуль admin в каждом установленных приложении. Такие модули, как ожидается, регистрируют модели в администрировании.

Обычно вам не нужно вызывать эту функцию напрямую, поскольку AdminConfig вызывает её при запуске Django.

Если вы используете пользовательское AdminSite, обычно импортируйте все классы ModelAdmin в свой код и зарегистрируйте их в пользовательском AdminSite. В этом случае, чтобы отключить автоматическое обнаружение, поместите 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin' в ваше значение INSTALLED_APPS.

ModelAdmin параметры

Класс ModelAdmin очень гибкий. Он предоставляет несколько способов настройки интерфейса. Все параметры определяются в подклассе ModelAdmin:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    date_hierarchy = 'pub_date'
ModelAdmin.actions

Список действий, доступных на странице списка изменений. Подробности см. в разделе Действия администрирования.

ModelAdmin.actions_on_top
ModelAdmin.actions_on_bottom

Управляет, где на странице отображается панель действий. По умолчанию администрирование отображает действия в верхней части страницы (actions_on_top = True; actions_on_bottom = False).

ModelAdmin.actions_selection_counter

Управляет отображением счётчика выделенных элементов рядом со списком действий. По умолчанию администрирование отображает его (actions_selection_counter = True).

ModelAdmin.date_hierarchy

Установите date_hierarchy в имя DateField или DateTimeField в вашей модели, и страница списка изменений будет включать навигацию по древовидному списку дат по этому полю.

Пример:

date_hierarchy = 'pub_date'

Вы также можете указать поле связанной модели, используя поиск __, например:

date_hierarchy = 'author__pub_date'

Это будет интеллектуально заполняться в зависимости от доступных данных, например, если все даты находятся в одном месяце, будет показана только древовидная навигация по дням.

Изменено в Django 1.11:

Была добавлена возможность ссылки на поля связанных моделей.

Примечание

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):
    fields = ('name', 'title', 'view_birth_date')

    def view_birth_date(self, obj):
        return obj.birth_date

    view_birth_date.empty_value_display = '???'
ModelAdmin.exclude

Если задан, этот атрибут должен быть списком имен полей, которые следует исключить из формы.

Например, рассмотрим следующую модель:

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=3)
    birth_date = models.DateField(blank=True, null=True)

Если вы хотите форму для модели Author, которая включает только поля name и title, вы должны указать fields или exclude следующим образом:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    fields = ('name', 'title')

class AuthorAdmin(admin.ModelAdmin):
    exclude = ('birth_date',)

Поскольку модель Author содержит только три поля, name, title и birth_date, формы, полученные из вышеперечисленных объявлений, будут содержать ровно те же поля.

ModelAdmin.fields

Используйте опцию fields, чтобы внести простые изменения в макет форм на страницах «добавление» и «изменение», таких как отображение только подмножества доступных полей, изменение их порядка или группировка их в строки. Например, вы можете определить упрощенную версию формы администрирования для модели django.contrib.flatpages.models.FlatPage следующим образом:

class FlatPageAdmin(admin.ModelAdmin):
    fields = ('url', 'title', 'content')

В приведенном выше примере будут отображаться только поля url, title и content последовательно в форме. fields может содержать значения, определенные в ModelAdmin.readonly_fields, которые будут отображаться только для чтения.

Для более сложных потребностей в макете см. опцию fieldsets.

Опция fields, в отличие от list_display, может содержать только имена полей в модели или форме, указанной в form. Она может содержать вызовы только в том случае, если они указаны в readonly_fields.

Чтобы отобразить несколько полей в одной строке, оберните эти поля в свои собственные кортежи. В этом примере поля url и title будут отображаться в одной строке, а поле content будет отображаться ниже их на отдельной строке:

class FlatPageAdmin(admin.ModelAdmin):
    fields = (('url', 'title'), 'content')

Примечание

Эту опцию fields не следует путать с ключом словаря fields, который находится внутри опции fieldsets, как описано в следующем разделе.

Если ни опция fields, ни fieldsets не указаны, Django по умолчанию отображает каждое поле, которое не является AutoField и имеет editable=True, в одной группе полей в том же порядке, что и в модели.

ModelAdmin.fieldsets

Установите fieldsets для управления макетом страниц администрирования «добавление» и «изменение».

fieldsets представляет собой список кортежей из двух элементов, где каждый кортеж представляет собой <fieldset> на странице формы администрирования. (<fieldset> — это «раздел» формы.)

Кортежи имеют формат (name, field_options), где name — это строка, представляющая заголовок группы полей, а field_options — словарь с информацией о группе полей, включая список полей, которые должны отображаться в ней.

Полный пример, взятый из модели django.contrib.flatpages.models.FlatPage:

from django.contrib import admin

class FlatPageAdmin(admin.ModelAdmin):
    fieldsets = (
        (None, {
            'fields': ('url', 'title', 'content', 'sites')
        }),
        ('Advanced options', {
            'classes': ('collapse',),
            'fields': ('registration_required', 'template_name'),
        }),
    )

Это приводит к отображению страницы администрирования:

../../../_images/fieldsets.png

Если ни опция fieldsets, ни fields не указаны, Django по умолчанию отобразит каждое поле, которое не является AutoField и имеет editable=True, в одной группе полей в том же порядке, что и в модели.

В словаре field_options могут быть следующие ключи:

  • fields

    Кортеж имен полей, которые необходимо отобразить в этой группе полей. Этот ключ обязателен.

    Пример:

    {
    'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
    }
    

    Как и с опцией fields, для отображения нескольких полей в одной строке, оберните эти поля в свои собственные кортежи. В этом примере поля first_name и last_name будут отображаться в одной строке:

    {
    'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
    }
    

    fields может содержать значения, определенные в readonly_fields, которые будут отображаться только для чтения.

    Если вы добавляете имя вызываемой функции в fields, то действует то же правило, что и с опцией fields: вызываемая функция должна быть указана в readonly_fields.

  • classes

    Список или кортеж, содержащий дополнительные CSS-классы, которые нужно применить к группе полей.

    Пример:

    {
    'classes': ('wide', 'extrapretty'),
    }
    

    Два полезных класса, определенные в стиле по умолчанию для администрирования, — collapse и wide. Группы полей со стилем collapse будут изначально свернуты в администрировании и заменены небольшой ссылкой «нажмите, чтобы развернуть». Группы полей со стилем wide получат дополнительное горизонтальное пространство.

  • description

    Строка с необязательным дополнительным текстом, который отображается в верхней части каждой группы полей под заголовком группы. Эта строка не отображается для TabularInline из-за его макета.

    Обратите внимание, что это значение не экранируется HTML, когда оно отображается в интерфейсе администрирования. Это позволяет вставлять HTML, если вы этого хотите. В качестве альтернативы, вы можете использовать обычный текст и django.utils.html.escape() для экранирования HTML-специальных символов.

ModelAdmin.filter_horizontal

По умолчанию, ManyToManyField отображается в админ-панели с <select multiple>. Однако много выборочные поля могут быть сложными в использовании при выборе многих элементов. Добавление ManyToManyField в этот список вместо этого будет использовать удобный незаметный интерфейс JavaScript «фильтр», который позволяет искать среди вариантов. Невыбранные и выбранные варианты отображаются в двух полях рядом. См. filter_vertical, чтобы использовать вертикальный интерфейс.

ModelAdmin.filter_vertical

То же самое, что и filter_horizontal, но использует вертикальное отображение интерфейса фильтра с полем невыбранных вариантов, отображающимся над полем выбранных вариантов.

ModelAdmin.form

По умолчанию для вашей модели динамически создается ModelForm. Он используется для создания формы, отображаемой на страницах добавления/изменения. Вы можете легко предоставить свою собственную ModelForm, чтобы переопределить любое поведение формы по умолчанию на страницах добавления/изменения. В качестве альтернативы вы можете настроить форму по умолчанию вместо указания совершенно новой, используя метод ModelAdmin.get_form().

Пример см. в разделе Добавление пользовательской валидации в админку.

Примечание

Если вы определяете атрибут Meta.model для ModelForm, вы также должны определить атрибут Meta.fields (или атрибут Meta.exclude). Однако, поскольку у админки есть свой способ определения полей, атрибут Meta.fields будет проигнорирован.

Если атрибут ModelForm будет использоваться только для админки, самым простым решением является опустить атрибут Meta.model, поскольку ModelAdmin предоставит правильную модель для использования. В качестве альтернативы вы можете установить fields = [] в классе Meta, чтобы удовлетворить валидацию на странице ModelForm.

Примечание

Если ваши ModelForm и ModelAdmin оба определяют опцию exclude, то ModelAdmin имеет приоритет:

from django import forms
from django.contrib import admin
from myapp.models import Person

class PersonForm(forms.ModelForm):

    class Meta:
        model = Person
        exclude = ['name']

class PersonAdmin(admin.ModelAdmin):
    exclude = ['age']
    form = PersonForm

В приведенном выше примере поле «возраст» будет исключено, а поле «имя» будет включено в сгенерированную форму.

ModelAdmin.formfield_overrides

Это предоставляет быстрый и грязный способ переопределения некоторых опций Field для использования в админке. formfield_overrides — это словарь, сопоставляющий класс поля с словарем аргументов, которые нужно передать полю во время создания.

Поскольку это немного абстрактно, давайте рассмотрим конкретный пример. Наиболее распространенное использование formfield_overrides — добавление пользовательского виджета для определенного типа поля. Представьте, что мы написали RichTextEditorWidget, который мы хотели бы использовать для больших текстовых полей вместо стандартного <textarea>. Вот как мы это сделаем:

from django.contrib import admin
from django.db import models

# Import our custom widget and our model from where they're defined
from myapp.models import MyModel
from myapp.widgets import RichTextEditorWidget

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }

Обратите внимание, что ключом в словаре является фактический класс поля, а не строка. Значение — это другой словарь; эти аргументы будут переданы методу __init__() поля формы. Подробнее см. в разделе API форм.

Предупреждение

Если вы хотите использовать пользовательский виджет с полем связи (т.е. ForeignKey или ManyToManyField), убедитесь, что вы не включили имя этого поля в raw_id_fields, radio_fields или autocomplete_fields.

formfield_overrides не позволит вам изменить виджет в полях связи, у которых установлены raw_id_fields, radio_fields или autocomplete_fields. Это связано с тем, что raw_id_fields, radio_fields и autocomplete_fields подразумевают собственные пользовательские виджеты.

ModelAdmin.inlines

См. объекты InlineModelAdmin ниже, а также ModelAdmin.get_formsets_with_inlines().

ModelAdmin.list_display

Установите list_display, чтобы контролировать, какие поля будут отображаться на странице списка изменений админки.

Пример:

list_display = ('first_name', 'last_name')

Если вы не установите list_display, в админке будет отображаться один столбец, показывающий представление __str__() каждого объекта.

У вас есть четыре возможных значения, которые могут быть использованы в list_display:

  • Поле модели. Например:

    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 в этом контексте — экземпляр модели. Вот полный пример модели:

    from django.contrib import admin
    from django.db import models
    
    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 отобразит __str__() связанного объекта.
  • ManyToManyField поля не поддерживаются, потому что это потребовало бы выполнения отдельного SQL-запроса для каждой строки в таблице. Если вы хотите сделать это все-таки, добавьте в свою модель пользовательский метод и укажите имя этого метода в list_display. (Подробнее о пользовательских методах в list_display см. ниже.)
  • Если поле — это BooleanField или NullBooleanField, Django отобразит красивую иконку «вкл.» или «выкл.» вместо True или False.
  • Если заданная строка — метод модели, ModelAdmin или вызываемый объект, Django по умолчанию экранирует вывод HTML. Чтобы экранировать пользовательский ввод и разрешить собственные тэги без экранирования, используйте format_html().

    Вот полный пример модели:

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        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, вы можете настроить заголовок колонки, добавив атрибут short_description к вызываемому объекту.
  • Если значение поля — None, пустая строка или итерируемый объект без элементов, Django отобразит - (тире). Вы можете переопределить это с помощью AdminSite.empty_value_display:

    from django.contrib import admin
    
    admin.site.empty_value_display = '(None)'
    

    Вы также можете использовать ModelAdmin.empty_value_display:

    class PersonAdmin(admin.ModelAdmin):
        empty_value_display = 'unknown'
    

    Или на уровне поля:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'birth_date_view')
    
        def birth_date_view(self, obj):
             return obj.birth_date
    
        birth_date_view.empty_value_display = 'unknown'
    
  • Если заданная строка — метод модели, ModelAdmin или вызываемый объект, возвращающий True или False, Django отобразит красивую иконку «вкл.» или «выкл.», если вы зададите атрибуту метода boolean значение True.

    Вот полный пример модели:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        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__() так же допустим в list_display, как и любой другой метод модели, поэтому вполне допустимо сделать это:

    list_display = ('__str__', 'some_other_field')
    
  • Обычно элементы list_display, которые не являются фактическими полями базы данных, нельзя использовать для сортировки (потому что Django выполняет всю сортировку на уровне базы данных).

    Однако, если элемент list_display представляет определённое поле базы данных, вы можете указать это, задав атрибут admin_order_field для этого элемента.

    Например:

    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)
    
        def colored_first_name(self):
            return format_html(
                '<span style="color: #{};">{}</span>',
                self.color_code,
                self.first_name,
            )
    
        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 в админке.

    Чтобы указать сортировку по убыванию с admin_order_field, вы можете использовать префикс дефиса для имени поля. Используя приведенный выше пример, это будет выглядеть так:

    colored_first_name.admin_order_field = '-first_name'
    

    admin_order_field поддерживает запросы к базе данных для сортировки по значениям в связанных моделях. Этот пример включает колонку «Имя автора» в списке отображения и позволяет сортировать по имени:

    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')
    
        def author_first_name(self, obj):
            return obj.author.first_name
    
        author_first_name.admin_order_field = 'author__first_name'
    
  • Элементы list_display также могут быть свойствами. Обратите внимание, что из-за того, как работают свойства в Python, установить short_description на свойстве возможно только при использовании функции property(), а не декоратора @property.

    Например:

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        def my_property(self):
            return self.first_name + ' ' + self.last_name
        my_property.short_description = "Full name of the person"
    
        full_name = property(my_property)
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('full_name',)
    
  • Имена полей в list_display также будут отображаться как классы CSS в выходном HTML-коде в форме column-<field_name> на каждом элементе <th>. Это может быть использовано для задания ширины столбцов в CSS-файле, например.
  • Django будет пытаться интерпретировать каждый элемент list_display в данном порядке:

    • Поле модели.
    • Вызываемый объект.
    • Строка, представляющая атрибут ModelAdmin.
    • Строка, представляющая атрибут модели.

    Например, если у вас есть first_name как поле модели и как атрибут ModelAdmin, будет использоваться поле модели.

ModelAdmin.list_display_links

Используйте list_display_links, чтобы управлять тем, какие поля в list_display должны быть связаны со страницей «изменить» объекта.

По умолчанию страница списка изменений будет связывать первый столбец — первое поле, указанное в list_display — со страницей изменения для каждого элемента. Но list_display_links позволяет изменить это:

  • Установите его в значение None, чтобы вообще не было ссылок.
  • Установите его в список или кортеж полей (в том же формате, что и в list_display), столбцы которых вы хотите преобразовать в ссылки.

    Вы можете указать одно или несколько полей. До тех пор, пока поля появляются в list_display, Django не имеет значения, сколько (или сколько) полей связано. Единственное требование состоит в том, что если вы хотите использовать list_display_links таким образом, вы должны определить list_display.

В этом примере поля first_name и last_name будут связаны на странице списка изменений:

class PersonAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'birthday')
    list_display_links = ('first_name', 'last_name')

В этом примере на странице списка изменений сетка не будет иметь ссылок:

class AuditEntryAdmin(admin.ModelAdmin):
    list_display = ('timestamp', 'message')
    list_display_links = None
ModelAdmin.list_editable

Установите list_editable в список имён полей в модели, которые позволят редактировать на странице списка изменений. То есть поля, перечисленные в list_editable, будут отображаться как виджеты формы на странице списка изменений, позволяя пользователям редактировать и сохранять несколько строк одновременно.

Примечание

list_editable взаимодействует с несколькими другими параметрами особым образом; вы должны обратить внимание на следующие правила:

  • Любое поле в list_editable также должно быть в list_display. Вы не можете редактировать поле, которое не отображается!
  • Одно и то же поле не может быть перечислено как в list_editable, так и в list_display_links — поле не может быть как формой, так и ссылкой.

Вы получите ошибку валидации, если любое из этих правил нарушено.

ModelAdmin.list_filter

Установите list_filter, чтобы активировать фильтры в правой боковой панели страницы списка изменений админки, как показано на следующем скриншоте:

../../../_images/list_filter.png

list_filter должен быть списком или кортежем элементов, где каждый элемент должен быть одного из следующих типов:

  • имя поля, где указанное поле должно быть либо BooleanField, CharField, DateField, DateTimeField, IntegerField, ForeignKey или ManyToManyField, например:

    class PersonAdmin(admin.ModelAdmin):
        list_filter = ('is_staff', 'company')
    

    Имена полей в list_filter также могут охватывать отношения, используя поиск __, например:

    class PersonAdmin(admin.UserAdmin):
        list_filter = ('company__name',)
    
  • класс, наследуемый от django.contrib.admin.SimpleListFilter, для которого необходимо предоставить атрибуты title и parameter_name и переопределить методы lookups и queryset, например:

    from datetime import date
    
    from django.contrib import admin
    from django.utils.translation import gettext_lazy as _
    
    class DecadeBornListFilter(admin.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 '90s')
            # 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(admin.ModelAdmin):
        list_filter = (DecadeBornListFilter,)
    

    Примечание

    Для удобства объект HttpRequest передаётся в методы lookups и queryset, например:

    class AuthDecadeBornListFilter(DecadeBornListFilter):
    
        def lookups(self, request, model_admin):
            if request.user.is_superuser:
                return super().lookups(request, model_admin)
    
        def queryset(self, request, queryset):
            if request.user.is_superuser:
                return super().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.get_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, например:

    class PersonAdmin(admin.ModelAdmin):
        list_filter = (
            ('is_staff', admin.BooleanFieldListFilter),
        )
    

    Вы можете ограничить выбор связанной модели объектами, участвующими в этом отношении, используя RelatedOnlyFieldListFilter:

    class BookAdmin(admin.ModelAdmin):
        list_filter = (
            ('author', admin.RelatedOnlyFieldListFilter),
        )
    

    Предполагая, что author — это ForeignKey модели User, это ограничит выбор list_filter пользователями, которые написали книгу, вместо перечисления всех пользователей.

    Примечание

    API FieldListFilter считается внутренним и может быть изменён.

Фильтры списка обычно появляются только в том случае, если у фильтра более одного варианта. Метод has_output() фильтра определяет, появляется ли он или нет.

Можно указать пользовательский шаблон для отображения фильтра списка:

class FilterWithCustomTemplate(admin.SimpleListFilter):
    template = "custom_template.html"

См. шаблон по умолчанию, предоставляемый Django (admin/filter.html), для конкретного примера.

ModelAdmin.list_max_show_all

Установите list_max_show_all, чтобы управлять количеством элементов, которые могут появиться на странице списка админки «Показать все». Админка будет отображать ссылку «Показать все» только если общее количество результатов меньше или равно этому параметру. По умолчанию это установлено в 200.

ModelAdmin.list_per_page

Установите list_per_page, чтобы управлять количеством элементов на каждой постраничной странице списка изменений админки. По умолчанию это установлено в 100.

ModelAdmin.list_select_related

Установите list_select_related, чтобы указать Django использовать select_related() при получении списка объектов на странице списка изменений админки. Это может сэкономить много баз данных.

Значение должно быть булевым значением, списком или кортежем. По умолчанию это False.

Когда значение равно True, select_related() всегда будет вызываться. Когда значение установлено в False, Django будет смотреть на list_display и вызывать select_related(), если есть какие-либо ForeignKey.

Если вам нужна более тонкая настройка, используйте кортеж (или список) в качестве значения для list_select_related. Пустой кортеж предотвратит вызов Django select_related вообще. Любой другой кортеж будет передан непосредственно в select_related в качестве параметров. Например:

class ArticleAdmin(admin.ModelAdmin):
    list_select_related = ('author', 'category')

вызовет select_related('author', 'category').

Если вам нужно указать динамическое значение, основанное на запросе, вы можете реализовать метод get_list_select_related().

ModelAdmin.ordering

Установите ordering, чтобы указать, как списки объектов должны сортироваться в представлениях Django admin. Это должен быть список или кортеж в том же формате, что и параметр ordering модели.

Если это не указано, Django admin будет использовать порядок по умолчанию модели.

Если вам нужно указать динамический порядок (например, в зависимости от пользователя или языка), вы можете реализовать метод get_ordering().

ModelAdmin.paginator

Класс Paginator, который будет использоваться для постраничного отображения. По умолчанию используется django.core.paginator.Paginator. Если у пользовательского класса Paginator нет такого же интерфейса конструктора, как у django.core.paginator.Paginator, вам также необходимо предоставить реализацию для ModelAdmin.get_paginator().

ModelAdmin.prepopulated_fields

Установите prepopulated_fields в словарь, сопоставляющий имена полей с полями, из которых они должны заполняться:

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

При установке указанные поля будут использовать немного JavaScript для заполнения из назначенных полей. Основное применение этой функции — автоматическое создание значения для SlugField полей из одного или нескольких других полей. Сгенерированное значение создаётся путём конкатенации значений исходных полей, а затем преобразованием этого результата в допустимый сокращённый адрес (например, замена тире на пробелы; приведение ASCII букв к нижнему регистру; удаление различных английских стоп-слов, таких как «a», «an», «as» и аналогичных).

Поля заполняются предварительно в формах добавления, но не в формах изменения. Обычно нежелательно, чтобы сокращённые адреса менялись после создания объекта (что привело бы к изменению URL объекта, если сокращённый адрес используется в нём).

prepopulated_fields не принимает DateTimeField, ForeignKey, OneToOneField и ManyToManyField поля.

ModelAdmin.preserve_filters

Админка теперь сохраняет фильтры на представлении списка после создания, редактирования или удаления объекта. Вы можете восстановить предыдущее поведение, очистив фильтры, установив этот атрибут в False.

ModelAdmin.radio_fields

По умолчанию Django admin использует интерфейс выпадающего списка (<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
Новое в Django 2.0.

autocomplete_fields — это список полей ForeignKey и/или ManyToManyField, которые вы хотите изменить на автодополнение Select2.

По умолчанию администратор использует интерфейс выпадающего списка (<select>) для этих полей. Иногда вы не хотите тратить время на выбор всех связанных элементов для отображения в раскрывающемся списке.

Ввод Select2 похож на стандартный ввод, но имеет функцию поиска, которая загружает опции асинхронно. Это быстрее и удобнее для пользователя, если связанная модель имеет много элементов.

Вы должны определить search_fields на связанном объекте в ModelAdmin, поскольку в поиске с автодополнением используется именно он.

Сортировка и постраничная навигация результатов контролируются связанным ModelAdmin методом get_ordering() и get_paginator().

В следующем примере у ChoiceAdmin есть поле автодополнения для ForeignKey к Question. Результаты фильтруются по полю question_text и сортируются по полю date_created:

class QuestionAdmin(admin.ModelAdmin):
    ordering = ['date_created']
    search_fields = ['question_text']

class ChoiceAdmin(admin.ModelAdmin):
    autocomplete_fields = ['question']

Рекомендации по производительности для больших наборов данных

Сортировка с использованием ModelAdmin.ordering может привести к проблемам производительности, так как сортировка по большому набору запросов будет медленной.

Также, если ваши поля поиска включают поля, которые не индексируются в базе данных, вы можете столкнуться с низкой производительностью на очень больших таблицах.

В этих случаях, рекомендуется написать свою собственную реализацию ModelAdmin.get_search_results() с использованием полнотекстового индексированного поиска.

Возможно, вам также потребуется изменить Paginator на очень больших таблицах, так как стандартный пагинатор всегда выполняет count() запрос. Например, вы можете переопределить стандартную реализацию свойства Paginator.count.

ModelAdmin.raw_id_fields

По умолчанию администратор Django использует интерфейс выпадающего списка (<select>) для полей, которые ForeignKey. Иногда вы не хотите тратить время на выбор всех связанных элементов для отображения в раскрывающемся списке.

raw_id_fields — это список полей, которые вы хотите изменить на виджет Input для ForeignKey или ManyToManyField:

class ArticleAdmin(admin.ModelAdmin):
    raw_id_fields = ("newspaper",)

Виджет raw_id_fields Input должен содержать первичный ключ, если поле является ForeignKey, или список значений, разделенных запятыми, если поле является ManyToManyField. Виджет raw_id_fields показывает кнопку лупы рядом с полем, которая позволяет пользователям искать и выбирать значение:

../../../_images/raw_id_fields.png
ModelAdmin.readonly_fields

По умолчанию администратор отображает все поля как редактируемые. Любые поля в этом параметре (которые должны быть list или tuple) будут отображать свои данные как есть и без возможности редактирования; они также исключаются из ModelForm, используемого для создания и редактирования. Обратите внимание, что при указании ModelAdmin.fields или ModelAdmin.fieldsets поля для только чтения должны быть присутствовать, чтобы отображаться (в противном случае они игнорируются).

Если readonly_fields используется без явного указания сортировки через ModelAdmin.fields или ModelAdmin.fieldsets, они будут добавлены в конец после всех редактируемых полей.

Поле только для чтения может не только отображать данные из поля модели, но и отображать результат метода модели или метода самого класса ModelAdmin. Это очень похоже на то, как работает ModelAdmin.list_display. Это обеспечивает простой способ использования интерфейса администратора для отображения статуса редактируемых объектов, например:

from django.contrib import admin
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe

class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('address_report',)

    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>")

    # short_description functions like a model field's verbose_name
    address_report.short_description = "Address"
ModelAdmin.save_as

Установите save_as, чтобы включить функцию «сохранить как новый» в формах изменения администратора.

Обычно у объектов есть три варианта сохранения: «Сохранить», «Сохранить и продолжить редактирование» и «Сохранить и добавить другой». Если save_as установлено в значение True, «Сохранить и добавить другой» будет заменено кнопкой «Сохранить как новый», которая создаст новый объект (с новым идентификатором) вместо обновления существующего.

По умолчанию, save_as установлено в значение False.

ModelAdmin.save_as_continue

При использовании save_as=True, по умолчанию перенаправление после сохранения нового объекта происходит на страницу изменения этого объекта. Если вы установите save_as_continue=False, перенаправление будет на страницу списка изменений.

По умолчанию save_as_continue установлено в значение True.

ModelAdmin.save_on_top

Установите save_on_top, чтобы добавить кнопки сохранения в верхней части форм изменения администратора.

Обычно кнопки сохранения отображаются только внизу форм. Если вы установите save_on_top, кнопки отобразятся и сверху, и снизу.

По умолчанию save_on_top установлено в значение False.

ModelAdmin.search_fields

Установите search_fields, чтобы включить поле поиска на странице списка изменений администратора. Оно должно содержать список имён полей, которые будут просматриваться при каждом запросе поиска пользователем в этом поле.

Эти поля должны быть каким-либо типом текстового поля, например, CharField или TextField. Вы также можете выполнить связанный поиск по ForeignKey или ManyToManyField с помощью нотации поиска «follow»:

search_fields = ['foreign_key__related_fieldname']

Например, если у вас есть запись блога с автором, следующая настройка позволит искать записи блога по электронному адресу автора:

search_fields = ['user__email']

Когда пользователь выполняет поиск в поле поиска администратора, Django разбивает запрос на слова и возвращает все объекты, содержащие каждое из слов, без учёта регистра, где каждое слово должно присутствовать хотя бы в одном из search_fields. Например, если search_fields установлено в ['first_name', 'last_name'], и пользователь ищет john lennon, Django выполнит запрос, эквивалентный следующему SQL-условию:

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 (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 (first_name ILIKE 'john' OR last_name ILIKE 'john')
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')

Обратите внимание, что входные данные запроса разбиваются по пробелам, поэтому, вследствие данного примера, в настоящее время невозможно искать все записи, в которых first_name точно равно 'john winston' (содержащие пробел).

@
Используйте оператор ‘@’ для выполнения полнотекстового соответствия. Это аналогично стандартному методу поиска, но использует индекс. В настоящее время это доступно только для MySQL.

Если вам нужно настроить поиск, вы можете использовать ModelAdmin.get_search_results() для предоставления дополнительных или альтернативных методов поиска.

ModelAdmin.show_full_result_count

Установите show_full_result_count, чтобы управлять отображением полного количества объектов на отфильтрованной странице администратора (например, 99 results (103 total)). Если этот параметр установлен в значение False, отображается текст, подобный 99 results (Show all).

По умолчанию show_full_result_count=True генерирует запрос для подсчёта всех строк таблицы, что может быть ресурсоёмким, если таблица содержит большое количество строк.

ModelAdmin.view_on_site

Установите view_on_site, чтобы управлять отображением ссылки «Просмотр на сайте». Эта ссылка должна перенаправлять вас на URL, где вы можете просмотреть сохранённый объект.

Это значение может быть логическим флагом или вызываемым объектом. Если True (по умолчанию), будет использоваться метод объекта get_absolute_url() для генерации URL.

Если ваш модель имеет метод get_absolute_url(), но вы не хотите, чтобы отображалась кнопка «Просмотр на сайте», вам нужно установить view_on_site на False:

from django.contrib import admin

class PersonAdmin(admin.ModelAdmin):
    view_on_site = False

В случае, если это вызываемый объект, он принимает экземпляр модели в качестве параметра. Например:

from django.contrib import admin
from django.urls import reverse

class PersonAdmin(admin.ModelAdmin):
    def view_on_site(self, obj):
        url = reverse('person-detail', kwargs={'slug': obj.slug})
        return 'https://example.com' + url

Настраиваемые параметры шаблонов

Раздел Переопределение шаблонов админки описывает, как переопределять или расширять стандартные шаблоны админки. Используйте следующие параметры для переопределения стандартных шаблонов, используемых представлениями 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
Добавлена в Django 1.11.

Путь к настраиваемому шаблону, используемому response_add(), response_change() и response_delete().

Методы модели

Предупреждение

При переопределении ModelAdmin.save_model() и ModelAdmin.delete_model(), ваш код должен сохранять/удалять объект. Они не предназначены для вето, а позволяют выполнять дополнительные операции.

ModelAdmin.save_model(request, obj, form, change) [source]

Метод save_model получает HttpRequest, экземпляр модели, экземпляр ModelForm и логическое значение, указывающее, добавляется или изменяется объект. Переопределение этого метода позволяет выполнять операции до или после сохранения. Вызовите super().save_model() для сохранения объекта с помощью Model.save().

Например, чтобы добавить request.user к объекту до сохранения:

from django.contrib import admin

class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.user = request.user
        super().save_model(request, obj, form, change)
ModelAdmin.delete_model(request, obj) [source]

Метод delete_model получает HttpRequest и экземпляр модели. Переопределение этого метода позволяет выполнять операции до или после удаления. Вызовите super().delete_model() для удаления объекта с помощью Model.delete().

ModelAdmin.save_formset(request, form, formset, change) [source]

Метод save_formset получает HttpRequest, родительский ModelForm экземпляр и логическое значение, указывающее, добавляется или изменяется родительский объект.

Например, чтобы добавить request.user к каждому изменённому экземпляру модели formset:

class ArticleAdmin(admin.ModelAdmin):
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for obj in formset.deleted_objects:
            obj.delete()
        for instance in instances:
            instance.user = request.user
            instance.save()
        formset.save_m2m()

См. также Сохранение объектов в formset.

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) [source]

Метод get_search_results изменяет список отображаемых объектов на те, которые соответствуют предоставленному поисковому запросу. Он принимает запрос, набор результатов запроса, применяющий текущие фильтры, и поисковый термин, предоставленный пользователем. Возвращает кортеж, содержащий набор результатов запроса, изменённый для реализации поиска, и логическое значение, указывающее, могут ли результаты содержать дубликаты.

По умолчанию выполняется поиск по полям, перечисленным в ModelAdmin.search_fields.

Этот метод может быть переопределён для реализации собственного метода поиска. Например, вы можете захотеть выполнить поиск по целочисленному полю или использовать внешний инструмент, такой как Solr или Haystack. Вы должны определить, могут ли изменения набора результатов запроса, реализованные вашим методом поиска, ввести дубликаты в результаты, и вернуть True во втором элементе возвращаемого значения.

Например, чтобы выполнить поиск по name и age, вы можете использовать:

class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age')
    search_fields = ('name',)

    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = 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, use_distinct

Эта реализация более эффективна, чем search_fields = ('name', '=age'), что приводит к сравнениям строк для числового поля, например, ... OR UPPER("polls_choice"."votes"::text) = UPPER('4') в PostgreSQL.

ModelAdmin.save_related(request, form, formsets, change) [source]

Метод save_related получает HttpRequest, родительский ModelForm экземпляр, список formset с inline-формами и логическое значение, указывающее, добавляется или изменяется родительский объект. Здесь вы можете выполнять любые операции до или после сохранения объектов, связанных с родительским объектом. Обратите внимание, что на данном этапе родительский объект и его форма уже сохранены.

ModelAdmin.get_autocomplete_fields(request)
Добавлена в Django 2.0.

Метод get_autocomplete_fields() получает HttpRequest и ожидается, что он вернёт list или tuple имён полей, которые будут отображаться с виджетом автозаполнения, как описано в разделе ModelAdmin.autocomplete_fields.

ModelAdmin.get_readonly_fields(request, obj=None)

Метод get_readonly_fields получает HttpRequest и obj редактируемый объект (или None в форме добавления) и ожидается, что он вернёт list или tuple имён полей, которые будут отображаться как только для чтения, как описано в разделе ModelAdmin.readonly_fields.

ModelAdmin.get_prepopulated_fields(request, obj=None)

Метод get_prepopulated_fields получает HttpRequest и obj, редактируемый объект (или None в форме добавления), и должен вернуть словарь, как описано в разделе ModelAdmin.prepopulated_fields.

ModelAdmin.get_list_display(request) [source]

Метод get_list_display получает HttpRequest и должен вернуть список или кортеж имён полей, которые будут отображаться на странице со списком изменений, как описано в разделе ModelAdmin.list_display.

ModelAdmin.get_list_display_links(request, list_display) [source]

Метод get_list_display_links получает HttpRequest и список или кортеж имён полей, возвращённых методом ModelAdmin.get_list_display(). Он должен вернуть список или кортеж имён полей, ссылки на которые будут вести на страницы редактирования на странице со списком изменений, как описано в разделе ModelAdmin.list_display_links.

ModelAdmin.get_exclude(request, obj=None)
Новое в Django 1.11.

Метод get_exclude получает HttpRequest и obj редактируемого объекта (или None в форме добавления) и должен вернуть список полей, как описано в ModelAdmin.exclude.

ModelAdmin.get_fields(request, obj=None)

Метод get_fields получает HttpRequest и obj редактируемого объекта (или None в форме добавления) и должен вернуть список полей, как описано в разделе ModelAdmin.fields.

ModelAdmin.get_fieldsets(request, obj=None)

Метод get_fieldsets получает HttpRequest и obj редактируемого объекта (или None в форме добавления) и должен вернуть список кортежей из двух элементов, где каждый кортеж представляет собой набор полей на странице админ-формы, как описано в разделе ModelAdmin.fieldsets.

ModelAdmin.get_list_filter(request) [source]

Метод get_list_filter получает HttpRequest и должен вернуть тот же тип последовательности, что и для атрибута list_filter.

ModelAdmin.get_list_select_related(request) [source]

Метод get_list_select_related получает HttpRequest и должен вернуть булево значение или список, как и атрибут ModelAdmin.list_select_related.

ModelAdmin.get_search_fields(request) [source]

Метод get_search_fields получает HttpRequest и должен вернуть тот же тип последовательности, что и для атрибута search_fields.

ModelAdmin.get_inline_instances(request, obj=None) [source]

Метод get_inline_instances получает HttpRequest и obj редактируемого объекта (или None в форме добавления) и должен вернуть список или кортеж объектов 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 являются экземплярами классов, определённых в inlines, иначе при добавлении связанных объектов может возникнуть ошибка “Bad Request”.

ModelAdmin.get_urls() [source]

Метод get_urls для ModelAdmin возвращает URL-адреса, которые будут использоваться для данного ModelAdmin, аналогично URLconf. Поэтому вы можете их расширять, как описано в диспетчере URL:

from django.contrib import admin
from django.template.response import TemplateResponse
from django.urls import path

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_view/', self.my_view),
        ]
        return my_urls + urls

    def my_view(self, request):
        # ...
        context = dict(
           # Include common variables for rendering the admin template.
           self.admin_site.each_context(request),
           # Anything else you want in the context...
           key=value,
        )
        return TemplateResponse(request, "sometemplate.html", context)

Если вы хотите использовать макет админки, расширяйте от admin/base_site.html:

{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}

Примечание

Обратите внимание, что пользовательские шаблоны включаются до стандартных URL-адресов админки: шаблоны URL админки очень гибкие и будут соответствовать почти всему, поэтому обычно вы захотите поместить свои пользовательские URL-адреса перед встроенными.

В этом примере, my_view будет доступен по адресу /admin/myapp/mymodel/my_view/ (предполагая, что URL-адреса админки включены в /admin/).

Однако функция self.my_view, зарегистрированная выше, страдает двумя проблемами:

  • Она не будет проверять разрешения, поэтому будет доступна всем пользователям.
  • Она не будет предоставлять какие-либо заголовки для предотвращения кэширования. Это означает, что если страница получает данные из базы данных, а кэширующий middleware активен, страница может показывать устаревшую информацию.

Поскольку это обычно не то, что вы хотите, Django предоставляет удобную обёртку для проверки разрешений и обозначения представления как некэшируемого. Эта обёртка — AdminSite.admin_view() (то есть self.admin_site.admin_view внутри экземпляра ModelAdmin); используйте её так:

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_view/', self.admin_site.admin_view(self.my_view))
        ]
        return my_urls + urls

Обратите внимание на обернутое представление в пятой строке выше:

path('my_view/', self.admin_site.admin_view(self.my_view))

Эта обёртка защитит self.my_view от несанкционированного доступа и применит декоратор django.views.decorators.cache.never_cache(), чтобы убедиться, что он не кэшируется, если активен middleware для кэширования.

Если страница кэшируется, но вы всё равно хотите, чтобы выполнялась проверка разрешений, вы можете передать аргумент 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) [source]

Возвращает класс 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) [source]

Возвращает пары (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 isinstance(inline, MyInline) and obj is None:
                continue
            yield inline.get_formset(request, obj), inline
ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs)

Метод formfield_for_foreignkey класса ModelAdmin позволяет вам переопределить стандартное поле формы для внешнего ключа. Например, чтобы вернуть подмножество объектов для этого поля внешнего ключа, основанного на пользователе:

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "car":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

Это использует экземпляр HttpRequest для фильтрации поля внешнего ключа Car, чтобы отобразить только автомобили, принадлежащие экземпляру User.

ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs)

Как и метод formfield_for_foreignkey, метод formfield_for_manytomany можно переопределить, чтобы изменить стандартное поле формы для поля «многие ко многим». Например, если владелец может владеть несколькими автомобилями, а автомобили могут принадлежать нескольким владельцам — это отношение «многие ко многим» — вы могли бы отфильтровать поле внешнего ключа Car, чтобы отобразить только автомобили, принадлежащие экземпляру User:

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "cars":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_manytomany(db_field, request, **kwargs)
ModelAdmin.formfield_for_choice_field(db_field, request, **kwargs)

Как и методы formfield_for_foreignkey и formfield_for_manytomany, метод formfield_for_choice_field можно переопределить, чтобы изменить стандартное поле формы для поля, которое объявило варианты выбора. Например, если варианты выбора, доступные суперпользователю, должны отличаться от тех, что доступны обычным сотрудникам, вы можете действовать следующим образом:

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_choice_field(self, db_field, request, **kwargs):
        if db_field.name == "status":
            kwargs['choices'] = (
                ('accepted', 'Accepted'),
                ('denied', 'Denied'),
            )
            if request.user.is_superuser:
                kwargs['choices'] += (('ready', 'Ready for deployment'),)
        return super().formfield_for_choice_field(db_field, request, **kwargs)

Примечание

Любой атрибут choices, установленный для formfield, будет ограничен только этим полем формы. Если соответствующее поле в модели имеет заданные варианты выбора, предоставленные варианты выбора форме должны быть корректным подмножеством этих вариантов, в противном случае отправка формы завершится ошибкой ValidationError при валидации модели перед сохранением.

ModelAdmin.get_changelist(request, **kwargs) [source]

Возвращает класс Changelist, который будет использоваться для отображения списка. По умолчанию используется django.contrib.admin.views.main.ChangeList. Наследуя этот класс, вы можете изменить поведение отображения списка.

ModelAdmin.get_changelist_form(request, **kwargs) [source]

Возвращает класс ModelForm для использования в Formset на странице списка изменений. Чтобы использовать пользовательскую форму, например:

from django import forms

class MyForm(forms.ModelForm):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_form(self, request, **kwargs):
        return MyForm

Примечание

Если вы определили атрибут Meta.model в ModelForm, вы также должны определить атрибут Meta.fields (или атрибут Meta.exclude). Однако, ModelAdmin игнорирует это значение, переопределяя его атрибутом ModelAdmin.list_editable. Самый простой способ — опустить атрибут Meta.model, так как ModelAdmin предоставит правильную модель для использования.

ModelAdmin.get_changelist_formset(request, **kwargs) [source]

Возвращает класс ModelFormSet для использования на странице списка изменений, если используется list_editable. Чтобы использовать пользовательский formset, например:

from django.forms import BaseModelFormSet

class MyAdminFormSet(BaseModelFormSet):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_formset(self, request, **kwargs):
        kwargs['formset'] = MyAdminFormSet
        return super().get_changelist_formset(request, **kwargs)
ModelAdmin.lookup_allowed(lookup, value)

Объекты на странице списка изменений можно фильтровать с помощью поисков из строки запроса URL. Так работает, например, list_filter. Поиски похожи на используемые в QuerySet.filter() (например, user__email=user@example.com). Поскольку поиски в строке запроса могут быть изменены пользователем, они должны быть очищены для предотвращения несанкционированного доступа к данным.

Методу lookup_allowed() передаётся путь поиска из строки запроса (например, 'user__email') и соответствующее значение (например, 'user@example.com'), и он возвращает булево значение, указывающее, разрешено ли фильтровать список изменений QuerySet с помощью параметров. Если lookup_allowed() возвращает False, генерируется исключение DisallowedModelAdminLookup (подкласс SuspiciousOperation).

По умолчанию lookup_allowed() разрешает доступ к локальным полям модели, путям полей, используемым в list_filter (но не путям из get_list_filter()), и поискам, необходимым для корректной работы limit_choices_to в raw_id_fields.

Переопределите этот метод, чтобы настроить разрешенные поиски для вашего подкласса ModelAdmin.

ModelAdmin.has_add_permission(request)

Должен вернуть True, если добавление объекта разрешено, False в противном случае.

ModelAdmin.has_change_permission(request, obj=None)

Должен вернуть True, если редактирование obj разрешено, False в противном случае. Если obj равно None, должен вернуть True или False, чтобы указать, разрешено ли редактирование объектов этого типа в целом (например, False будет интерпретироваться как означающее, что текущий пользователь не имеет права редактировать ни один объект этого типа).

ModelAdmin.has_delete_permission(request, obj=None)

Должен вернуть True, если удаление obj разрешено, False в противном случае. Если obj равно None, должен вернуть True или False, чтобы указать, разрешено ли удаление объектов этого типа в целом (например, False будет интерпретироваться как означающее, что текущий пользователь не имеет права удалять ни один объект этого типа).

END_OF_DOCUMENT_MARKER
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 на ModelAdmin возвращает QuerySet всех экземпляров модели, которые могут быть изменены сайтом администратора. Один из случаев использования переопределения этого метода — отображение объектов, принадлежащих вошедшему в систему пользователю:

class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(author=request.user)
ModelAdmin.message_user(request, message, level=messages.INFO, extra_tags='', fail_silently=False) [source]

Отправляет сообщение пользователю, используя 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) [source]

Возвращает экземпляр пагинатора, который нужно использовать для этого представления. По умолчанию создаёт экземпляр paginator.

ModelAdmin.response_add(request, obj, post_url_continue=None) [source]

Определяет HttpResponse для стадии add_view().

response_add вызывается после отправки формы администратора и сразу после создания и сохранения объекта и всех связанных экземпляров. Вы можете переопределить его, чтобы изменить стандартное поведение после создания объекта.

ModelAdmin.response_change(request, obj) [source]

Определяет HttpResponse для стадии change_view().

response_change вызывается после отправки формы администратора и сразу после сохранения объекта и всех связанных экземпляров. Вы можете переопределить его, чтобы изменить стандартное поведение после изменения объекта.

ModelAdmin.response_delete(request, obj_display, obj_id) [source]

Определяет HttpResponse для стадии delete_view().

response_delete вызывается после удаления объекта. Вы можете переопределить его, чтобы изменить стандартное поведение после удаления объекта.

obj_display — строка с именем удалённого объекта.

obj_id — сериализованный идентификатор, используемый для извлечения объекта, который требуется удалить.

ModelAdmin.get_changeform_initial_data(request) [source]

Обработчик для начальных данных в формах изменения администратора. По умолчанию поля получают начальные значения из параметров GET. Например, ?name=initial_value задаст начальное значение поля name как initial_value.

Этот метод должен возвращать словарь в формате {'fieldname': 'fieldval'}:

def get_changeform_initial_data(self, request):
    return {'name': 'custom_initial_value'}

Другие методы

ModelAdmin.add_view(request, form_url='', extra_context=None) [source]

Представление Django для страницы добавления экземпляра модели. См. примечание ниже.

ModelAdmin.change_view(request, object_id, form_url='', extra_context=None) [source]

Представление Django для страницы редактирования экземпляра модели. См. примечание ниже.

ModelAdmin.changelist_view(request, extra_context=None) [source]

Представление Django для страницы списка экземпляров модели/действий. См. примечание ниже.

ModelAdmin.delete_view(request, object_id, extra_context=None) [source]

Представление Django для страницы подтверждения удаления экземпляра(ов) модели. См. примечание ниже.

ModelAdmin.history_view(request, object_id, extra_context=None) [source]

Представление Django для страницы, которая отображает историю изменений для данного экземпляра модели.

В отличие от методов типа ModelAdmin, описанных в предыдущем разделе, эти пять методов фактически предназначены для вызова как представлений Django из обработчика диспетчеризации URL-адресов приложения администрирования для отображения страниц, которые обрабатывают операции CRUD с экземплярами моделей. В результате полное переопределение этих методов значительно изменит поведение приложения администрирования.

Одной из распространённых причин переопределения этих методов является дополнение данных контекста, предоставляемых шаблону, который отображает представление. В следующем примере представление изменения переопределяется таким образом, чтобы предоставленный отображаемому шаблону набор данных включал дополнительную сопоставляющую информацию, которая в противном случае была бы недоступна:

class MyModelAdmin(admin.ModelAdmin):

    # A template for a very customized change view:
    change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'

    def get_osm_info(self):
        # ...
        pass

    def change_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['osm_data'] = self.get_osm_info()
        return super().change_view(
            request, object_id, form_url, extra_context=extra_context,
        )

Эти представления возвращают TemplateResponse экземпляры, что позволяет легко настроить данные ответа перед рендерингом. Более подробная информация приведена в документации TemplateResponse.

ModelAdmin определения ресурсов

Иногда вам нужно добавить немного CSS и/или JavaScript к страницам добавления/изменения. Это можно сделать, используя внутренний класс Media в вашем классе ModelAdmin:

class ArticleAdmin(admin.ModelAdmin):
    class Media:
        css = {
            "all": ("my_styles.css",)
        }
        js = ("my_code.js",)

Приложение staticfiles добавляет STATIC_URL (или MEDIA_URL, если STATIC_URL является None) в начало любого пути к ресурсам. Применяются те же правила, что и при определении ресурсов форм.

jQuery

Django-админка использует библиотеку jQuery.

Для предотвращения конфликтов с пользовательскими скриптами или библиотеками jQuery Django (версия 2.2.3) имеет пространство имён django.jQuery. Если вы хотите использовать jQuery в собственном JavaScript для админки без включения второй копии, вы можете использовать объект django.jQuery на страницах списков, добавления и редактирования.

Класс ModelAdmin по умолчанию требует jQuery, поэтому нет необходимости добавлять jQuery в список ресурсов медиа вашего ModelAdmin, если у вас нет специфической потребности. Например, если вам нужен jQuery в глобальном пространстве имён (например, при использовании сторонних плагинов jQuery) или вам нужна более новая версия jQuery, вам нужно будет включить свою собственную копию.

Django предоставляет как нескомпрессированные, так и «минифицированные» версии jQuery, соответственно jquery.js и jquery.min.js.

ModelAdmin и InlineModelAdmin имеют свойство media, которое возвращает список объектов Media, хранящих пути к файлам JavaScript для форм и/или наборов форм. Если DEBUG равно True, оно вернёт нескомпрессированные версии различных файлов JavaScript, включая jquery.js; в противном случае вернёт «минифицированные» версии.

Добавление пользовательской валидации в админ-панель

Добавление пользовательской валидации данных в админ-панели довольно просто. Автоматический админ-интерфейс использует django.forms, а класс ModelAdmin предоставляет возможность определять собственную форму:

class ArticleAdmin(admin.ModelAdmin):
    form = MyArticleAdminForm

MyArticleAdminForm можно определить в любом месте, при условии, что вы импортируете его по мере необходимости. Теперь внутри вашей формы вы можете добавить собственную пользовательскую валидацию для любого поля:

class MyArticleAdminForm(forms.ModelForm):
    def clean_name(self):
        # do something that validates your data
        return self.cleaned_data["name"]

Важно использовать здесь ModelForm, иначе могут возникнуть ошибки. Смотрите документацию по формам в разделе пользовательской валидации и, более конкретно, в примечаниях к валидации форм моделей для получения дополнительной информации.

InlineModelAdmin объекты

class InlineModelAdmin
class TabularInline [source]
class StackedInline [source]

Интерфейс администрирования имеет возможность редактировать модели на одной странице с родительской моделью. Это так называемые вложенные элементы. Предположим, у вас есть эти две модели:

from django.db import models

class Author(models.Model):
   name = models.CharField(max_length=100)

class Book(models.Model):
   author = models.ForeignKey(Author, on_delete=models.CASCADE)
   title = models.CharField(max_length=100)

Вы можете редактировать книги, написанные автором, на странице автора. Вы добавляете вложенные элементы в модель, указав их в ModelAdmin.inlines:

from django.contrib import admin

class BookInline(admin.TabularInline):
    model = Book

class AuthorAdmin(admin.ModelAdmin):
    inlines = [
        BookInline,
    ]

Django предоставляет два подкласса InlineModelAdmin:

  • TabularInline
  • StackedInline

Различие между ними заключается только в используемой для их отображения шаблоне.

InlineModelAdmin параметры

InlineModelAdmin разделяет многие функции с ModelAdmin и добавляет свои собственные (общие функции фактически определены в суперклассе BaseModelAdmin). Общие функции следующие:

  • form
  • fieldsets
  • fields
  • formfield_overrides
  • exclude
  • filter_horizontal
  • filter_vertical
  • ordering
  • prepopulated_fields
  • get_queryset()
  • radio_fields
  • readonly_fields
  • raw_id_fields
  • formfield_for_choice_field()
  • formfield_for_foreignkey()
  • formfield_for_manytomany()
  • has_add_permission()
  • has_change_permission()
  • has_delete_permission()
  • has_module_permission()

Класс InlineModelAdmin добавляет:

InlineModelAdmin.model

Модель, которую использует вложенный элемент. Это обязательно.

InlineModelAdmin.fk_name

Имя внешнего ключа в модели. В большинстве случаев это будет обрабатываться автоматически, но fk_name необходимо указать явно, если есть более одного внешнего ключа к той же родительской модели.

InlineModelAdmin.formset

По умолчанию это BaseInlineFormSet. Использование собственного набора форм предоставляет множество возможностей для настройки. Вложенные элементы основаны на наборах форм моделей.

InlineModelAdmin.form

Значение для form по умолчанию ModelForm. Это то, что передаётся в inlineformset_factory() при создании набора форм для данного вложенного элемента.

Предупреждение

При написании пользовательской валидации для InlineModelAdmin форм будьте осторожны при написании валидации, которая опирается на особенности родительской модели. Если родительская модель не пройдёт валидацию, она может остаться в несогласованном состоянии, как описано в предупреждении в Валидации на ModelForm.

InlineModelAdmin.classes

Список или кортеж, содержащий дополнительные CSS классы, которые необходимо применить к набору полей, отображаемых для вложенных элементов. По умолчанию None. Как и в случае с классами, настроенными в fieldsets, вложенные элементы с классом collapse будут изначально свёрнуты, а в их заголовке будет отображаться небольшая ссылка "показать".

InlineModelAdmin.extra

Это управляет количеством дополнительных форм, которые будет отображать формасет, помимо начальных форм. Для получения дополнительной информации см. документацию по формасетам.

Для пользователей с браузерами, поддерживающими JavaScript, предоставляется ссылка «Добавить ещё», которая позволяет добавлять любое количество дополнительных строк помимо тех, которые были добавлены в результате аргумента extra.

Динамическая ссылка не будет отображаться, если количество отображаемых в данный момент форм превышает max_num или если у пользователя отключен JavaScript.

InlineModelAdmin.get_extra() также позволяет настраивать количество дополнительных форм.

InlineModelAdmin.max_num

Это управляет максимальным количеством форм для отображения в строке. Это не напрямую соответствует количеству объектов, но может, если значение достаточно мало. Для получения дополнительной информации см. Ограничение количества редактируемых объектов.

InlineModelAdmin.get_max_num() также позволяет настраивать максимальное количество дополнительных форм.

InlineModelAdmin.min_num

Это управляет минимальным количеством форм для отображения в строке. Для получения дополнительной информации см. modelformset_factory().

InlineModelAdmin.get_min_num() также позволяет настраивать минимальное количество отображаемых форм.

InlineModelAdmin.raw_id_fields

По умолчанию, админка Django использует интерфейс выпадающего списка (<select>) для полей, которые являются ForeignKey. Иногда вы не хотите нести издержки, связанные с необходимостью выбора всех связанных экземпляров для отображения в выпадающем списке.

raw_id_fields — это список полей, которые вы хотите изменить на виджет Input для использования либо с ForeignKey, либо с ManyToManyField:

class BookInline(admin.TabularInline):
    model = Book
    raw_id_fields = ("pages",)
InlineModelAdmin.template

Шаблон, используемый для отображения строки на странице.

InlineModelAdmin.verbose_name

Переопределение verbose_name, найденного в внутреннем классе Meta модели.

InlineModelAdmin.verbose_name_plural

Переопределение verbose_name_plural, найденного в внутреннем классе Meta модели.

InlineModelAdmin.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).

Работа с моделью с двумя или более внешними ключами к той же родительской модели

Иногда возможно иметь более одного внешнего ключа к той же модели. Взгляните на эту модель, например:

from django.db import models

class Friendship(models.Model):
    to_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="friends")
    from_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="from_friends")

Если вы хотите отобразить строку на страницах добавления/изменения админки Person, вам необходимо явно определить внешний ключ, так как сделать это автоматически не получится:

from django.contrib import admin
from myapp.models import Friendship

class FriendshipInline(admin.TabularInline):
    model = Friendship
    fk_name = "to_person"

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        FriendshipInline,
    ]

Работа с моделями "многие ко многим"

По умолчанию, виджеты админки для отношений "многие ко многим" будут отображаться в той модели, которая содержит фактическую ссылку на ManyToManyField. В зависимости от вашего определения ModelAdmin, каждое поле "многие ко многим" в вашей модели будет представлено стандартным HTML-виджетом <select multiple>, горизонтальным или вертикальным фильтром или виджетом raw_id_admin. Однако также можно заменить эти виджеты строками.

Предположим, у нас есть следующие модели:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, related_name='groups')

Если вы хотите отобразить отношения "многие ко многим" с помощью строки, вы можете сделать это, определив объект InlineModelAdmin для отношения:

from django.contrib import admin

class MembershipInline(admin.TabularInline):
    model = Group.members.through

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

class GroupAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]
    exclude = ('members',)

В этом примере есть две особенности, на которые стоит обратить внимание.

Во-первых, класс MembershipInline ссылается на Group.members.through. Атрибут through — ссылка на модель, которая управляет отношением "многие ко многим". Эта модель автоматически создаётся Django, когда вы определяете поле "многие ко многим".

Во-вторых, необходимо вручную исключить поле members. Django отображает виджет админки для поля "многие ко многим" в модели, которая определяет отношение (в данном случае, Group). Если вы хотите использовать строку модели для представления отношения "многие ко многим", вы должны указать админке Django, что не нужно отображать этот виджет — иначе у вас на странице админки окажется два виджета для управления отношением.

Обратите внимание, что при использовании этой техники сигналы m2m_changed не срабатывают. Это потому, что, насколько это касается админки, through — это просто модель с двумя полями внешнего ключа, а не отношение "многие ко многим".

Во всех остальных отношениях InlineModelAdmin точно такая же, как любая другая. Вы можете настроить её внешний вид, используя любые стандартные свойства ModelAdmin.

Работа с промежуточными моделями "многие ко многим"

Когда вы указываете промежуточную модель, используя аргумент through к ManyToManyField, админка не будет отображать виджет по умолчанию. Это потому, что каждый экземпляр промежуточной модели требует больше информации, чем можно отобразить в одном виджете, и макет, необходимый для нескольких виджетов, будет варьироваться в зависимости от промежуточной модели.

Однако мы по-прежнему хотим иметь возможность редактировать эту информацию в строке. К счастью, это легко сделать с помощью админских строк. Предположим, у нас есть следующие модели:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

Первый шаг в отображении этой промежуточной модели в админке — определение класса строки для модели Membership:

class MembershipInline(admin.TabularInline):
    model = Membership
    extra = 1

Этот простой пример использует значения по умолчанию для модели InlineModelAdmin, и ограничивает количество дополнительных форм добавления одной. Это можно настроить, используя любые доступные опции для классов InlineModelAdmin.

Теперь создайте административные представления для моделей Person и Group:

class PersonAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

class GroupAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

Наконец, зарегистрируйте модели Person и Group в административном сайте:

admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)

Теперь ваш административный сайт настроен для редактирования объектов Membership в строке из страниц деталей Person или Group.

Использование обобщённых отношений как строки

Возможно использование строки с обобщённо связанными объектами. Предположим, у вас есть следующие модели:

from django.contrib.contenttypes.fields import GenericForeignKey
from django.db import models

class Image(models.Model):
    image = models.ImageField(upload_to="images")
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

class Product(models.Model):
    name = models.CharField(max_length=100)

Если вы хотите разрешить редактирование и создание экземпляра Image на Product, добавив/изменив представления, вы можете использовать GenericTabularInline или GenericStackedInline (оба являются подклассами GenericInlineModelAdmin), предоставленными admin. Они реализуют табличные и стопочные визуальные макеты для форм, представляющих встроенные объекты, соответственно, как и их необобщённые аналоги. Они ведут себя как любые другие встроенные объекты. В вашем admin.py для этого примера приложения:

from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline

from myproject.myapp.models import Image, Product

class ImageInline(GenericTabularInline):
    model = Image

class ProductAdmin(admin.ModelAdmin):
    inlines = [
        ImageInline,
    ]

admin.site.register(Product, ProductAdmin)

См. документацию contenttypes для более подробной информации.

Переопределение шаблонов админки

Относительно легко переопределять многие шаблоны, которые модуль админки использует для генерации различных страниц сайта админки. Вы даже можете переопределить несколько из этих шаблонов для конкретного приложения или конкретной модели.

Настройка каталогов шаблонов админки вашего проекта

Файлы шаблонов админки находятся в каталоге contrib/admin/templates/admin.

Чтобы переопределить один или несколько из них, сначала создайте каталог admin в каталоге вашего проекта templates. Это может быть любой из каталогов, указанных в параметре DIRS бэкенда DjangoTemplates в настройке TEMPLATES. Если вы настроили параметр 'loaders', убедитесь, что 'django.template.loaders.filesystem.Loader' появляется перед 'django.template.loaders.app_directories.Loader', чтобы система загрузки шаблонов находила ваши пользовательские шаблоны раньше, чем те, что включены с django.contrib.admin.

Внутри этого каталога admin создайте подкаталоги, названные в соответствии с вашими приложениями. Внутри этих подкаталогов приложений создайте подкаталоги, названные в соответствии с вашими моделями. Обратите внимание, что приложение админки будет преобразовывать имя модели в нижний регистр при поиске каталога, поэтому убедитесь, что вы назвали каталог в нижнем регистре, если вы собираетесь запускать приложение на файловой системе, чувствительной к регистру.

Чтобы переопределить шаблон админки для конкретного приложения, скопируйте и отредактируйте шаблон из каталога django/contrib/admin/templates/admin и сохраните его в одном из созданных вами каталогов.

Например, если мы хотели добавить инструмент в представление списка изменений для всех моделей в приложении с именем my_app, мы скопировали бы contrib/admin/templates/admin/change_list.html в каталог templates/admin/my_app/ нашего проекта и внесли необходимые изменения.

Если мы хотели добавить инструмент в представление списка изменений только для конкретной модели с именем «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">{% trans "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">{% trans "View on site" %}</a>
        </li>
    {% endif %}
{% endblock %}

И всё! Если мы разместили этот файл в каталоге templates/admin/my_app, наша ссылка появится на форме изменения для всех моделей в приложении my_app.

Шаблоны, которые можно переопределить по приложению или модели

Не каждый шаблон в contrib/admin/templates/admin можно переопределить по приложению или по модели. Следующие можно:

  • app_index.html
  • change_form.html
  • change_list.html
  • delete_confirmation.html
  • object_history.html
  • popup_response.html
Изменено в Django 1.11:

Была добавлена возможность переопределения шаблона popup_response.html.

Для тех шаблонов, которые нельзя переопределить таким образом, вы всё равно можете переопределить их для всего своего проекта. Просто поместите новую версию в каталог templates/admin. Это особенно полезно для создания пользовательских страниц 404 и 500.

Примечание

Некоторые шаблоны админки, такие как change_list_results.html, используются для рендеринга пользовательских тегов включения. Их можно переопределить, но в таких случаях вам, вероятно, лучше создать свою версию интересующего вас тега и дать ему другое имя. Таким образом, вы можете использовать его выборочно.

Шаблоны корневой и входной страниц

Если вы хотите изменить шаблоны главной страницы, входа или выхода, вам лучше создать свой экземпляр AdminSite (см. ниже) и изменить свойства AdminSite.index_template, AdminSite.login_template или AdminSite.logout_template.

AdminSite объекты

class AdminSite(name='admin') [source]

Сайт Django админки представлен экземпляром django.contrib.admin.sites.AdminSite; по умолчанию создаётся экземпляр этого класса как django.contrib.admin.site, и вы можете зарегистрировать в нём свои модели и экземпляры ModelAdmin.

При создании экземпляра AdminSite вы можете указать уникальное имя экземпляра, используя аргумент name в конструкторе. Это имя экземпляра используется для идентификации экземпляра, особенно при обращении к URL-адресам админки. Если имя экземпляра не указано, будет использовано имя по умолчанию admin. См. Настройка класса AdminSite для примера настройки класса AdminSite.

AdminSite атрибуты

Шаблоны могут переопределять или расширять базовые шаблоны админки, как описано в Переопределение шаблонов админки.

AdminSite.site_header

Текст, который будет отображаться в верхней части каждой страницы админки, как строка. По умолчанию, это «Django administration».

AdminSite.site_title

Текст, который будет отображаться в нижней части каждой страницы админки, как строка. По умолчанию, это «Django site admin».

AdminSite.site_url

URL для ссылки «Просмотреть сайт» в верхней части каждой страницы админки. По умолчанию, site_url является /. Установите его в None, чтобы удалить ссылку.

Для сайтов, работающих на подпути, метод each_context() проверяет, установлен ли request.META['SCRIPT_NAME'] в текущем запросе, и использует это значение, если site_url не установлено на значение, отличное от /.

AdminSite.index_title

Текст, который будет отображаться в верхней части главной страницы админки, как строка. По умолчанию, это «Site administration».

AdminSite.index_template

Путь к пользовательскому шаблону, который будет использоваться для главной страницы админки.

AdminSite.app_index_template

Путь к пользовательскому шаблону, который будет использоваться для страницы индекса приложения админки.

AdminSite.empty_value_display

Строка, используемая для отображения пустых значений в списке изменений админки. По умолчанию — тире. Это значение также можно переопределить для каждого ModelAdmin и для пользовательского поля в рамках ModelAdmin, установив атрибут empty_value_display для поля. См. ModelAdmin.empty_value_display для примеров.

AdminSite.login_template

Путь к пользовательскому шаблону, который будет использоваться для страницы входа в админку.

AdminSite.login_form

Подкласс AuthenticationForm, который будет использоваться для страницы входа в админку.

AdminSite.logout_template

Путь к пользовательскому шаблону, который будет использоваться представлением выхода из администрирования.

AdminSite.password_change_template

Путь к пользовательскому шаблону, который будет использоваться представлением смены пароля в администрировании.

AdminSite.password_change_done_template

Путь к пользовательскому шаблону, который будет использоваться представлением завершения смены пароля в администрировании.

AdminSite методы

AdminSite.each_context(request) [source]

Возвращает словарь переменных для контекста шаблона каждой страницы в админ-панели.

По умолчанию включает следующие переменные и значения:

  • site_header: AdminSite.site_header
  • site_title: AdminSite.site_title
  • site_url: AdminSite.site_url
  • has_permission: AdminSite.has_permission()
  • available_apps: список приложений из реестра приложений, доступных для текущего пользователя. Каждый элемент списка — это словарь, представляющий приложение со следующими ключами:

    • app_label: имя приложения
    • app_url: URL страницы индекса приложения в админ-панели
    • has_module_perms: булево значение, указывающее, разрешен ли доступ к странице индекса модуля для текущего пользователя
    • models: список моделей, доступных в приложении

    Каждая модель — это словарь со следующими ключами:

    • object_name: имя класса модели
    • name: множественное число имени модели
    • perms: отслеживание dict, add, и change разрешений
    • admin_url: URL страницы администрирования списка моделей
    • add_url: URL страницы администрирования для добавления новой записи модели
AdminSite.has_permission(request) [source]

Возвращает True, если у пользователя с заданными HttpRequest есть разрешение на просмотр хотя бы одной страницы в админ-панели. По умолчанию требует, чтобы User.is_active и User.is_staff были True.

AdminSite.register(model_or_iterable, admin_class=None, **options) [source]

Регистрирует заданный класс модели (или итерируемый список классов) с заданными admin_class. По умолчанию admin_class устанавливается на ModelAdmin (по умолчанию). Если заданы аргументы ключевых слов — например, list_display — они будут применены в качестве опций к классу администрирования.

Выбрасывает ImproperlyConfigured, если модель является абстрактной, и django.contrib.admin.sites.AlreadyRegistered, если модель уже зарегистрирована.

Подключение экземпляров AdminSite в ваш URLconf

Последний шаг настройки Django администрирования — подключение экземпляра AdminSite в ваш URLconf. Для этого укажите заданный URL к методу AdminSite.urls. Использование include() не обязательно.

В данном примере, экземпляр по умолчанию AdminSite, django.contrib.admin.site, зарегистрирован по URL /admin/

# urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

Настройка класса AdminSite

Если вам нужно создать собственную админ-панель с индивидуальным поведением, вы можете наследоваться от AdminSite и переопределить или добавить необходимые функции. Затем просто создайте экземпляр вашего класса-наследника AdminSite (так же, как и любой другой Python класс) и зарегистрируйте ваши модели и классы-наследники ModelAdmin с ним вместо стандартной панели. Наконец, обновите myproject/urls.py, чтобы он ссылался на ваш класс-наследник AdminSite.

from django.contrib.admin import AdminSite

from .models import MyModel

class MyAdminSite(AdminSite):
    site_header = 'Monty Python administration'

admin_site = MyAdminSite(name='myadmin')
admin_site.register(MyModel)
from django.urls import path

from myapp.admin import admin_site

urlpatterns = [
    path('myadmin/', admin_site.urls),
]

Обратите внимание, что при использовании собственного экземпляра AdminSite вам может не потребоваться автоматическое обнаружение модулей admin, так как вы, скорее всего, импортируете все модули admin в вашем модуле myproject.admin. Это означает, что вам нужно использовать 'django.contrib.admin.apps.SimpleAdminConfig' вместо 'django.contrib.admin' в настройке INSTALLED_APPS.

Несколько админ-панелей в одном URLconf

Легко создать несколько экземпляров админ-панели на одном сайте Django. Просто создайте несколько экземпляров AdminSite и укажите для каждого свой URL.

В этом примере, URL /basic-admin/ и /advanced-admin/ отображают отдельные версии админ-панели — используя экземпляры AdminSite myproject.admin.basic_site и myproject.admin.advanced_site соответственно:

# urls.py
from django.urls import path
from myproject.admin import advanced_site, basic_site

urlpatterns = [
    path('basic-admin/', basic_site.urls),
    path('advanced-admin/', advanced_site.urls),
]

Экземпляры AdminSite принимают единственный аргумент в конструкторе — имя, которое может быть любым. Этот аргумент становится префиксом к именам URL для целей обратного преобразования. Это необходимо только в случае использования более одной AdminSite.

Добавление представлений в админ-панель

Как и ModelAdmin, AdminSite предоставляет метод get_urls(), который можно переопределить для определения дополнительных представлений для панели. Чтобы добавить новое представление в вашу админ-панель, расширьте метод get_urls(), включив шаблон для вашего нового представления.

Примечание

Любое представление, которое использует админ-шаблоны или расширяет базовый админ-шаблон, должно установить request.current_app перед отрисовкой шаблона. Оно должно быть установлено либо в self.name, если ваше представление находится на AdminSite, или в self.admin_site.name, если ваше представление находится на ModelAdmin.

Добавление функции сброса пароля

Вы можете добавить функцию сброса пароля в админ-панель, добавив несколько строк в ваш URLconf. В частности, добавьте эти четыре шаблона:

from django.contrib.auth import views as auth_views

path(
    'admin/password_reset/',
    auth_views.PasswordResetView.as_view(),
    name='admin_password_reset',
),
path(
    'admin/password_reset/done/',
    auth_views.PasswordResetDoneView.as_view(),
    name='password_reset_done',
),
path(
    'reset/<uidb64>/<token>/',
    auth_views.PasswordResetConfirmView.as_view(),
    name='password_reset_confirm',
),
path(
    'reset/done/',
    auth_views.PasswordResetCompleteView.as_view(),
    name='password_reset_complete',
),

(Предполагается, что вы добавили администрирование в admin/ и необходимо расположить URL, начинающиеся с ^admin/ перед строкой, включающей сам админ-приложение).

Наличие URL с именем admin_password_reset заставит ссылку «забыли пароль?» отображаться на стандартной странице входа в администрирование под полем для пароля.

LogEntry объекты

class models.LogEntry

Класс LogEntry отслеживает добавления, изменения и удаления объектов, выполненные через админ-панель.

LogEntry атрибуты

LogEntry.action_time

Дата и время действия.

LogEntry.user

Пользователь (экземпляр AUTH_USER_MODEL), который выполнил действие.

LogEntry.content_type

Тип содержимого ContentType изменённого объекта.

LogEntry.object_id

Текстовое представление первичного ключа изменённого объекта.

LogEntry.object_repr

Представление объекта repr() после изменения.

LogEntry.action_flag

Тип записанного действия: ADDITION, CHANGE, DELETION.

Например, для получения списка всех добавлений, сделанных через админку:

from django.contrib.admin.models import ADDITION, LogEntry

LogEntry.objects.filter(action_flag=ADDITION)
LogEntry.change_message

Подробное описание изменения. В случае редактирования, например, сообщение содержит список изменённых полей. Сайт админки Django форматирует это содержимое как JSON-структуру, чтобы get_change_message() мог пересобрать сообщение на языке текущего пользователя. Пользовательский код может установить его как обычную строку. Вам рекомендуется использовать метод get_change_message() для получения этого значения, вместо прямого доступа.

LogEntry методы

LogEntry.get_edited_object()

Сокращение, возвращающее ссылку на объект.

LogEntry.get_change_message()

Форматирует и переводит change_message на язык текущего пользователя. Сообщения, созданные до Django 1.10, всегда будут отображаться на языке, на котором они были записаны.

Обращение к URL-адресам админки

При развертывании AdminSite, предоставленные этим сайтом представления доступны с помощью системы обратного преобразования URL-адресов Django (Система обратного преобразования URL-адресов).

Админ-сайт AdminSite предоставляет следующие именованные URL-шаблоны:

Страница Имя URL Параметры
Главная страница index
Вход login
Выход logout
Смена пароля password_change
Смена пароля (завершено) password_change_done
i18n JavaScript jsi18n
Страница индекса приложения app_list app_label
Переадресация на страницу объекта view_on_site content_type_id, object_id

Каждый экземпляр ModelAdmin предоставляет дополнительный набор именованных URL-адресов:

Страница Имя URL Параметры
Список изменений {{ app_label }}_{{ model_name }}_changelist
Добавление {{ app_label }}_{{ model_name }}_add
История {{ app_label }}_{{ model_name }}_history object_id
Удаление {{ app_label }}_{{ model_name }}_delete object_id
Изменение {{ app_label }}_{{ model_name }}_change object_id

UserAdmin предоставляет именованный URL:

Страница Имя URL Параметры
Смена пароля auth_user_password_change user_id

Эти именованные URL-адреса зарегистрированы в пространстве имён приложения admin и с пространством имён экземпляра, соответствующим имени экземпляра сайта.

Например, если вы хотите получить ссылку на представление изменения для конкретного объекта Choice (из приложения polls) в стандартной админке, вы вызовете:

>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,))

Это найдет первый зарегистрированный экземпляр приложения админки (независимо от имени экземпляра) и перенаправит на представление изменения объектов poll.Choice в этом экземпляре.

Если вы хотите найти URL в определенном экземпляре админки, укажите имя этого экземпляра в качестве подсказки для вызова обратного преобразования. Например, если вы хотите получить представление админки от экземпляра под именем custom, вам необходимо вызвать:

>>> change_url = reverse('admin:polls_choice_change', args=(c.id,), current_app='custom')

Подробнее см. документацию по обратному преобразованию именованных URL-адресов.

Для упрощения обращения к URL-адресам админки в шаблонах Django предоставляет фильтр admin_urlname, который принимает действие в качестве аргумента:

{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>

Действие в примерах выше соответствует последней части имён URL-адресов для экземпляров ModelAdmin, описанных выше. Переменная opts может быть любым объектом, у которого есть атрибуты app_label и model_name, и обычно предоставляется представлениями админки для текущей модели.

Декоратор staff_member_required

staff_member_required(redirect_field_name='next', login_url='admin:login') [source]

Этот декоратор используется для представлений админки, требующих авторизации. Представление, украшенное этим декоратором, будет работать следующим образом:

  • Если пользователь вошел в систему, является членом персонала (User.is_staff=True) и активен (User.is_active=True), представление выполняется нормально.
  • В противном случае запрос перенаправляется на URL, указанный параметром login_url, с исходным запрошенным путем в переменной запроса, заданной redirect_field_name. Например: /admin/login/?next=/admin/polls/question/3/.

Пример использования:

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def my_view(request):
    ...

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.0/ref/contrib/admin/index/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API