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

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

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

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

Обзор

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

Если вы не используете шаблон проекта по умолчанию, вот требования:

  1. Добавить 'django.contrib.admin'и его зависимость - django.contrib.auth, django.contrib.contenttypes, django.contrib.messages, и django.contrib.sessions- к вашей INSTALLED_APPSобстановке.

  2. Настройка DjangoTemplates бэкенд в вашей TEMPLATESобстановке с django.template.context_processors.request, django.contrib.auth.context_processors.authи django.contrib.messages.context_processors.messagesв 'context_processors'опции OPTIONS.

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

    django.template.context_processors.requestбыл добавлен как требование в 'context_processors'опции для поддержки нового AdminSite.enable_nav_sidebar.

  3. Если вы настроили MIDDLEWAREпараметры, django.contrib.auth.middleware.AuthenticationMiddlewareи django.contrib.messages.middleware.MessageMiddlewareдолжны быть включены.

  4. Подключите URL-адреса администратора к вашему URLconf .

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

Если вам нужно создать пользователя для входа в систему, используйте createsuperuser команду. По умолчанию для входа в систему администратора требуется, чтобы у пользователя был установлен is_staffатрибут True.

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

Другие темы

Смотрите также

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

Возникли проблемы? Попробуйте FAQ: Админ .

ModelAdminобъекты

класс ModelAdmin

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( * модели , сайт = django.contrib.admin.sites.site )

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

from django.contrib import admin
from .models import Author

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

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

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

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

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

Открытие админ-файлов

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

класс apps.AdminConfig

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

класс apps.SimpleAdminConfig

Этот класс работает вроде AdminConfig, но не вызывает autodiscover().

default_site

Пунктирный путь импорта к классу административного сайта по умолчанию или к вызываемому объекту, который возвращает экземпляр сайта. По умолчанию 'django.contrib.admin.sites.AdminSite'. См. Раздел Переопределение сайта администратора по умолчанию для использования.

autodiscover()

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

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

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

ModelAdminварианты

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

from django.contrib import admin

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

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

ModelAdmin.actions_on_top
ModelAdmin.actions_on_bottom

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

ModelAdmin.actions_selection_counter

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

ModelAdmin.date_hierarchy

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

Пример:

date_hierarchy = 'pub_date'

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

date_hierarchy = 'author__pub_date'

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

Примечание

date_hierarchyиспользует QuerySet.datetimes()внутренне. Пожалуйста, обратитесь к его документации, чтобы узнать о некоторых предостережениях, когда включена поддержка часовых поясов ( ).USE_TZ = True

ModelAdmin.empty_value_display

Этот атрибут переопределяет отображаемое значение по умолчанию для пустых полей записи ( None, пустой строки и т. Д.). Значение по умолчанию - -(тире). Например:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    empty_value_display = '-empty-'

Вы также можете переопределить empty_value_displayдля всех административных страниц AdminSite.empty_value_displayили для определенных полей, например:

from django.contrib import admin

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

    @admin.display(empty_value='???')
    def view_birth_date(self, obj):
        return obj.birth_date
Изменено в Django 3.2:

empty_valueАргумент display()декоратора эквивалентен установка 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',)

Поскольку модель Автор имеет только три поля, name, titleи birth_date, формы , вытекающие из указанных деклараций будет содержать одни и те же поля.

ModelAdmin.fields

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

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

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

Если требуется более сложный макет, см. fieldsetsОпцию.

Параметр fieldsпринимает те же типы значений, что и list_display, за исключением того, что вызываемые объекты не принимаются. Имена моделей и методов администрирования модели будут использоваться только в том случае, если они указаны в readonly_fields.

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

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

Примечание

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

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

ModelAdmin.fieldsets

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

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

Два кортежа имеют формат , где - строка, представляющая заголовок набора полей, и словарь информации о наборе полей, включая список полей, которые будут отображаться в нем.(name, field_options)namefield_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, в одном FIELDSET, в том же порядке, что и поля определены в модели.

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на сайте администратора отображается с расширением . Однако поля с множественным выбором могут быть трудными для использования при выборе большого количества элементов. При добавлении в этот список вместо этого будет использоваться изящный ненавязчивый интерфейс «фильтра» JavaScript, который позволяет выполнять поиск по параметрам. Невыбранные и выбранные параметры отображаются в двух полях рядом. См. Использование вертикального интерфейса.<select multiple>ManyToManyFieldfilter_vertical

ModelAdmin.filter_vertical

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

ModelAdmin.form

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

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

Примечание

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

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

Примечание

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

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

class PersonForm(forms.ModelForm):

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

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

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

ModelAdmin.formfield_overrides

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

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

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

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

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

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

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

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

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

ModelAdmin.inlines

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

ModelAdmin.list_display

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

Пример:

list_display = ('first_name', 'last_name')

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

Есть четыре типа значений, которые можно использовать в list_display. Все, кроме самых простых, могут использовать display() декоратор, который используется для настройки представления поля:

  • Имя модельного поля. Например:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name')
    
  • Вызываемый объект, который принимает один аргумент - экземпляр модели. Например:

    @admin.display(description='Name')
    def upper_case_name(obj):
        return ("%s %s" % (obj.first_name, obj.last_name)).upper()
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = (upper_case_name,)
    
  • Строка, представляющая ModelAdminметод, который принимает один аргумент - экземпляр модели. Например:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('upper_case_name',)
    
        @admin.display(description='Name')
        def upper_case_name(self, obj):
            return ("%s %s" % (obj.first_name, obj.last_name)).upper()
    
  • Строка, представляющая атрибут или метод модели (без обязательных аргументов). Например:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        @admin.display(description='Birth decade')
        def decade_born_in(self):
            return '%d’s' % (self.birthday.year // 10 * 10)
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'decade_born_in')
    

Следует отметить несколько особых случаев list_display:

  • Если это поле ForeignKey, Django отобразит __str__()соответствующий объект.

  • ManyToManyFieldполя не поддерживаются, потому что это повлечет за собой выполнение отдельного оператора SQL для каждой строки в таблице. Если вы все же хотите сделать это, дайте вашей модели собственный метод и добавьте имя этого метода в list_display. (См. Ниже дополнительные сведения о пользовательских методах в list_display.)

  • Если поле является BooleanField, Django не будет отображаться, «нет», или значок довольно «да» , «неизвестный» вместо True, Falseили None.

  • Если данная строка является методом модели ModelAdminили вызываемым объектом, Django по умолчанию экранирует вывод в HTML. Чтобы избежать ввода пользователя и разрешить использование собственных тегов без экранирования, используйте format_html().

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

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        @admin.display
        def colored_name(self):
            return format_html(
                '<span style="color: #{};">{} {}</span>',
                self.color_code,
                self.first_name,
                self.last_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'colored_name')
    
  • Как уже было продемонстрировано в некоторых примерах, при использовании вызываемого объекта, метода модели или ModelAdminметода вы можете настроить заголовок столбца, заключив вызываемый объект в display()декоратор и передав descriptionаргумент.

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

    descriptionАргумент display()декоратора эквивалентен установка 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')
    
        @admin.display(empty_value='unknown')
        def birth_date_view(self, obj):
             return obj.birth_date
    
    Изменено в Django 3.2:

    empty_valueАргумент display()декоратора эквивалентен установка empty_value_displayатрибута функции отображения непосредственно в предыдущих версиях. Прямая установка атрибута по-прежнему поддерживается для обратной совместимости.

  • Если данная строка является методом модели ModelAdminили вызываемым объектом, который возвращает True, Falseили None, Django отобразит симпатичный значок «да», «нет» или «неизвестно», если вы заключите метод в display()декоратор, передав booleanаргумент с помощью значение установлено на True:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        @admin.display(boolean=True)
        def born_in_fifties(self):
            return 1950 <= self.birthday.year < 1960
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'born_in_fifties')
    
    Изменено в Django 3.2:

    booleanАргумент display()декоратора эквивалентен установка booleanатрибута функции отображения непосредственно в предыдущих версиях. Прямая установка атрибута по-прежнему поддерживается для обратной совместимости.

  • Этот __str__()метод так же применим, list_displayкак и любой другой модельный метод, так что это нормально:

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

    Однако, если элемент list_displayпредставляет собой определенное поле базы данных, вы можете указать этот факт, используя display()декоратор метода, передав orderingаргумент:

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        @admin.display(ordering='first_name')
        def colored_first_name(self):
            return format_html(
                '<span style="color: #{};">{}</span>',
                self.color_code,
                self.first_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'colored_first_name')
    

    Вышеупомянутое укажет Django упорядочить по first_nameполю при попытке выполнить сортировку colored_first_nameв админке.

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

    @admin.display(ordering='-first_name')
    

    orderingАргумент поддерживает запрос , поиски для сортировки значений по соответствующим моделям. Этот пример включает столбец «имя автора» в отображение списка и позволяет отсортировать его по имени:

    class Blog(models.Model):
        title = models.CharField(max_length=255)
        author = models.ForeignKey(Person, on_delete=models.CASCADE)
    
    class BlogAdmin(admin.ModelAdmin):
        list_display = ('title', 'author', 'author_first_name')
    
        @admin.display(ordering='author__first_name')
        def author_first_name(self, obj):
            return obj.author.first_name
    

    Выражения запроса могут использоваться с orderingаргументом:

    from django.db.models import Value
    from django.db.models.functions import Concat
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        @admin.display(ordering=Concat('first_name', Value(' '), 'last_name'))
        def full_name(self):
            return self.first_name + ' ' + self.last_name
    
    Изменено в Django 3.2:

    orderingАргумент display()декоратора эквивалентен установка admin_order_fieldатрибута функции отображения непосредственно в предыдущих версиях. Прямая установка атрибута по-прежнему поддерживается для обратной совместимости.

  • Элементами list_displayтакже могут быть свойства:

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        @property
        @admin.display(
            ordering='last_name',
            description='Full name of the person',
        )
        def full_name(self):
            return self.first_name + ' ' + self.last_name
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('full_name',)
    

    Обратите внимание, что @propertyдолжно быть выше @display. Если вы используете старый способ - установка атрибутов отображения связанных напрямую , а не с помощью display()декоратора - следует помнить , что property()функция и не@property декоратор должны быть использованы:

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

  • Django попытается интерпретировать каждый элемент list_displayв следующем порядке:

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

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

Используется 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выбор пользователями, написавшими книгу, вместо того, чтобы перечислять всех пользователей.

    Вы можете фильтровать пустые значения, используя EmptyFieldListFilter, который может фильтровать как пустые строки, так и нули, в зависимости от того, что поле позволяет хранить:

    class BookAdmin(admin.ModelAdmin):
        list_filter = (
            ('title', admin.EmptyFieldListFilter),
        )
    

    Примечание

    FieldListFilterAPI считается внутренним и могут быть изменены.

    Примечание

    GenericForeignKey Поле не поддерживается.

    Новое в Django 3.1:

    EmptyFieldListFilterКласс был добавлен.

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

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

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

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

ModelAdmin.list_max_show_all

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

ModelAdmin.list_per_page

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

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

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

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

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

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

позвоню .select_related('author', 'category')

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

Примечание

ModelAdminигнорирует этот атрибут, если select_related()он уже был вызван в списке изменений QuerySet.

ModelAdmin.ordering

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

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

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

Соображения производительности при упорядочивании и сортировке

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

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

ModelAdmin.paginator

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

ModelAdmin.prepopulated_fields

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

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

Если установлено, данные поля будут использовать немного JavaScript для заполнения из назначенных полей. Основное использование этой функции - автоматическое создание значения для SlugFieldполей из одного или нескольких других полей. Сгенерированное значение создается путем объединения значений исходных полей, а затем путем преобразования этого результата в допустимую краткую информацию (например, путем замены пробелов на тире и строчных букв ASCII).

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

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

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

В более старых версиях из сгенерированных значений удалены различные английские стоп-слова.

ModelAdmin.preserve_filters

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

ModelAdmin.radio_fields

По умолчанию администратор Django использует интерфейс выбора (<select>) для полей, которые установлены ForeignKeyили choicesустановлены. Если поле присутствует radio_fields, Django будет использовать вместо него интерфейс с переключателями. Предполагая , что groupэто ForeignKeyна Personмодели:

class PersonAdmin(admin.ModelAdmin):
    radio_fields = {"group": admin.VERTICAL}

У вас есть выбор: использовать HORIZONTALили VERTICALиз django.contrib.adminмодуля.

Не включайте поле, radio_fieldsесли оно не установлено ForeignKeyили choices.

ModelAdmin.autocomplete_fields

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

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

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

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

Чтобы избежать несанкционированного раскрытия данных, пользователи должны иметь разрешение viewили changeна связанный объект, чтобы использовать автозаполнение.

Заказ и разбиение на страницы результатов контролируются соответствующий ModelAdmin«ы get_ordering()и get_paginator()методов.

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

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

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

Вопросы производительности для больших наборов данных

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

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

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

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

ModelAdmin.raw_id_fields

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

raw_id_fields- это список полей, которые вы хотите превратить в Inputвиджет для a 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',)

    # description functions like a model field's verbose_name
    @admin.display(description='Address')
    def address_report(self, instance):
        # assuming get_full_address() returns a list of strings
        # for each line of the address and you want to separate each
        # line by a linebreak
        return format_html_join(
            mark_safe('<br>'),
            '{}',
            ((line,) for line in instance.get_full_address()),
        ) or mark_safe("<span class='errors'>I can't determine this address.</span>")
ModelAdmin.save_as

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

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

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

ModelAdmin.save_as_continue

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

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

ModelAdmin.save_on_top

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

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

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

ModelAdmin.search_fields

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

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

search_fields = ['foreign_key__related_fieldname']

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

search_fields = ['user__email']

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

WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')

Поисковый запрос может содержать фразы в кавычках с пробелами. Например, если пользователь ищет или , Django выполнит эквивалент этого предложения SQL :"john winston"'john winston'WHERE

WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')

Если вы не хотите использовать его icontainsв качестве поиска, вы можете использовать любой поиск, добавив его в поле. Например, вы могли бы использовать exact , установив search_fieldsдля ['first_name__exact'].

Также доступны некоторые (более старые) ярлыки для указания поиска по полю. Вы можете добавить к полю search_fieldsследующие символы, что эквивалентно добавлению __<lookup>в поле:

Приставка Уважать
^ startswith
знак равно iexact
@ search
Никто icontains

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

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

Добавлена ​​поддержка поиска по цитируемым фразам с пробелами.

ModelAdmin.show_full_result_count

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

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

ModelAdmin.sortable_by

По умолчанию на странице списка изменений разрешена сортировка по всем полям модели (и вызываемым объектам, которые используют orderingаргумент display()декоратора или имеют admin_order_fieldатрибут), указанным в list_display.

Если вы хотите , чтобы отключить сортировку для некоторых столбцов, установите sortable_byв коллекции (например list, tupleили set) подмножества , list_displayчто вы хотите быть сортировкой. Пустая коллекция отключает сортировку для всех столбцов.

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

ModelAdmin.view_on_site

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

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

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

from django.contrib import admin

class PersonAdmin(admin.ModelAdmin):
    view_on_site = False

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

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

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

Параметры настраиваемого шаблона

В разделе « Переопределение шаблонов администратора » описывается, как переопределить или расширить стандартные шаблоны администратора. Используйте следующие параметры, чтобы переопределить шаблоны по умолчанию, используемые ModelAdminпредставлениями:

ModelAdmin.add_form_template

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

ModelAdmin.change_form_template

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

ModelAdmin.change_list_template

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

ModelAdmin.delete_confirmation_template

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

ModelAdmin.delete_selected_confirmation_template

Путь к настраиваемому шаблону, используемый методом delete_selectedдействия для отображения страницы подтверждения при удалении одного или нескольких объектов. См. Документацию по действиям .

ModelAdmin.object_history_template

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

ModelAdmin.popup_response_template

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

ModelAdminметоды

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

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

ModelAdmin.save_model( запрос , объект , форма , изменение )

Этому 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( запрос , объект )

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

ModelAdmin.delete_queryset( запрос , набор запросов )

delete_queryset()Метод с учетом HttpRequestи QuerySetобъектов , которые должны быть удалены. Перекрыть этот метод , чтобы настроить процесс удаления для «удалить выбранные объекты» действий .

ModelAdmin.save_formset( запрос , форма , набор форм , изменение )

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

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

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

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

ModelAdmin.get_ordering( запрос )

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( запрос , набор запросов , условие_поиска )

В 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

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

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

ModelAdmin.get_autocomplete_fields( запрос )

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

ModelAdmin.get_readonly_fields( запрос , obj = Нет )

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

ModelAdmin.get_prepopulated_fields( запрос , obj = Нет )

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

ModelAdmin.get_list_display( запрос )

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

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

ModelAdmin.get_exclude( запрос , obj = Нет )

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

ModelAdmin.get_fields( запрос , obj = Нет )

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

ModelAdmin.get_fieldsets( запрос , obj = Нет )

get_fieldsetsМетод , учитывая HttpRequestи obj редактируется (или Noneна форме добавления) , и , как ожидается, возвращает список двух кортежей, в котором каждый из двух кортежа представляет <fieldset>на странице формы администратора, как описано выше в ModelAdmin.fieldsetsразделе.

ModelAdmin.get_list_filter( запрос )

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

Этому get_list_select_relatedметоду присваивается значение, HttpRequestи он должен возвращать логическое значение или список, как и ModelAdmin.list_select_related делает.

ModelAdmin.get_search_fields( запрос )

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

ModelAdmin.get_sortable_by( запрос )

get_sortable_by()Метод будет принят HttpRequestи , как ожидается , вернуть коллекцию (например list, tupleили set) имен полей , которые будут сортируются на странице списка изменений.

Его реализация по умолчанию возвращается, sortable_byесли она установлена, иначе откладывается get_list_display().

Например, чтобы предотвратить сортировку одного или нескольких столбцов:

class PersonAdmin(admin.ModelAdmin):

    def get_sortable_by(self, request):
        return {*self.get_list_display(request)} - {'rank'}
ModelAdmin.get_inline_instances( запрос , obj = Нет )

get_inline_instancesМетод , учитывая HttpRequestи objредактируется (или Noneна форме добавления) , и , как ожидается, возвращать listили tupleиз InlineModelAdmin объектов, как описано ниже в InlineModelAdmin разделе. Например, следующее будет возвращать встроенные строки без фильтрации по умолчанию на основе разрешений на добавление, изменение, удаление и просмотр:

class MyModelAdmin(admin.ModelAdmin):
    inlines = (MyInline,)

    def get_inline_instances(self, request, obj=None):
        return [inline(self.model, self.admin_site) for inline in self.inlines]

Если вы переопределите этот метод, убедитесь, что возвращенные встроенные строки являются экземплярами классов, определенных в, в противном случае inlinesвы можете столкнуться с ошибкой « неверный запрос» при добавлении связанных объектов.

ModelAdmin.get_inlines( запрос , объект )

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

ModelAdmin.get_urls()

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

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

path('my_view/', self.admin_site.admin_view(self.my_view, cacheable=True))

ModelAdminпредставления имеют model_adminатрибуты. У других AdminSiteпредставлений есть admin_siteатрибуты.

ModelAdmin.get_form( запрос , obj = None , ** kwargs )

Возвращает ModelFormкласс для использования во взглядах администратора добавления и изменения, см add_view()и change_view().

Базовая реализация использует modelform_factory() для создания подкласса form, измененного такими атрибутами, как fields и exclude. Так, например, если вы хотите предложить суперпользователям дополнительные поля, вы можете поменять местами другую базовую форму, например:

class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['form'] = MySuperuserForm
        return super().get_form(request, obj, **kwargs)

Вы также можете ModelFormнапрямую вернуть собственный класс.

ModelAdmin.get_formsets_with_inlines( запрос , obj = Нет )

Дает пары ( FormSet, InlineModelAdmin) для использования в представлениях администратора, добавления и изменения.

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

class MyModelAdmin(admin.ModelAdmin):
    inlines = [MyInline, SomeOtherInline]

    def get_formsets_with_inlines(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if not isinstance(inline, MyInline) or obj is not None:
                yield inline.get_formset(request, obj), inline
ModelAdmin.formfield_for_foreignkey( db_field , запрос , ** kwargs )

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

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

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

Для более сложных фильтров вы можете использовать ModelForm.__init__()метод фильтрации на основе instanceвашей модели (см. Поля, которые обрабатывают отношения ). Например:

class CountryAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['capital'].queryset = self.instance.cities.all()

class CountryAdmin(admin.ModelAdmin):
    form = CountryAdminForm
ModelAdmin.formfield_for_manytomany( db_field , запрос , ** 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 , запрос , ** kwargs )

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

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

Примечание

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

ModelAdmin.get_changelist( просьба , ** kwargs )

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

ModelAdmin.get_changelist_form( просьба , ** kwargs )

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

from django import forms

class MyForm(forms.ModelForm):
    pass

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

Примечание

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

ModelAdmin.get_changelist_formset( просьба , ** kwargs )

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

from django.forms import BaseModelFormSet

class MyAdminFormSet(BaseModelFormSet):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_formset(self, request, **kwargs):
        kwargs['formset'] = MyAdminFormSet
        return super().get_changelist_formset(request, **kwargs)
ModelAdmin.lookup_allowed( поиск , значение )

Объекты на странице списка изменений можно фильтровать с помощью поиска из строки запроса URL. Вот как это list_filterработает, например. Поиск аналогичен тому, что используется в QuerySet.filter()(например [email protected]). Поскольку поисковые запросы в строке запроса могут управляться пользователем, они должны быть очищены, чтобы предотвратить несанкционированное раскрытие данных.

lookup_allowed()Метод задается путем подстановки из строки запроса (например , 'user__email') и соответствующего значения (например '[email protected]'), и возвращает логическое значение , указывающее , является ли фильтрование списка изменений - й с QuerySetиспользованием параметров допускаются. Если lookup_allowed()возвращается False, DisallowedModelAdminLookup (подкласс SuspiciousOperation) возбуждается.

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

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

ModelAdmin.has_view_permission( запрос , obj = Нет )

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

Реализация по умолчанию возвращается, Trueесли у пользователя есть разрешение на «изменение» или «просмотр».

ModelAdmin.has_add_permission( запрос )

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

ModelAdmin.has_change_permission( запрос , obj = Нет )

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

ModelAdmin.has_delete_permission( запрос , obj = Нет )

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

ModelAdmin.has_module_permission( запрос )

Должен возвращаться, Trueесли отображение модуля на странице индекса администратора и доступ к странице индекса модуля разрешен, в Falseпротивном случае. Используется User.has_module_perms()по умолчанию. Игнорирование это не ограничивает доступ к просматривать, добавлять, изменять или удалять виды, has_view_permission(), has_add_permission(), has_change_permission(), и has_delete_permission()следует использовать для этого.

ModelAdmin.get_queryset( запрос )

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( запрос , сообщение , уровень = messages.INFO , extra_tags = '' , fail_silently = False )

Отправляет сообщение пользователю через django.contrib.messages серверную часть. См. Пример настраиваемого ModelAdmin .

Аргументы ключевых слов позволяют изменять уровень сообщения, добавлять дополнительные теги CSS или автоматически завершать работу, если contrib.messagesфреймворк не установлен. Эти аргументы ключевых слов соответствуют аргументам для django.contrib.messages.add_message(), см. Документацию по этой функции для получения дополнительных сведений. Одно отличие состоит в том, что уровень может передаваться как строковая метка в дополнение к целому числу / константе.

ModelAdmin.get_paginator( Запрос , QuerySet , per_page , сироты = 0 , allow_empty_first_page = True )

Возвращает экземпляр разбиения на страницы для использования в этом представлении. По умолчанию создает экземпляр paginator.

ModelAdmin.response_add( запрос , объект , post_url_continue = Нет )

Определяет HttpResponseдля add_view()сцены.

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

ModelAdmin.response_change( запрос , объект )

Определяет HttpResponseдля change_view()сцены.

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

ModelAdmin.response_delete( запрос , obj_display , obj_id )

Определяет HttpResponseдля delete_view()сцены.

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

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

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

ModelAdmin.get_changeform_initial_data( запрос )

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

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

def get_changeform_initial_data(self, request):
    return {'name': 'custom_initial_value'}
ModelAdmin.get_deleted_objects( объекты , запрос )

Крючок для настройки процесса удаления из delete_view()и «Удалить» действие .

objsАргументом является однородной итерацией объектов (а QuerySet или список экземпляров модели) должны быть удален, и requestявляется HttpRequest.

Этот метод должен возвращать 4 кортежа .(deleted_objects, model_count, perms_needed, protected)

deleted_objectsэто список строк, представляющих все объекты, которые будут удалены. Если есть какие-либо связанные объекты, которые нужно удалить, список является вложенным и включает эти связанные объекты. Список форматируется в шаблоне с помощью unordered_listфильтра.

model_count- это словарь, сопоставляющий каждую модель verbose_name_pluralс количеством удаляемых объектов.

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

protectedпредставляет собой список строк, представляющих все защищенные связанные объекты, которые нельзя удалить. Список отображается в шаблоне.

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

ModelAdmin.add_view( запрос , form_url = '' , extra_context = None )

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

ModelAdmin.change_view( Запрос , object_id , FORM_URL = '' , extra_context = нет )

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

ModelAdmin.changelist_view( запрос , extra_context = None )

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

ModelAdmin.delete_view( запрос , object_id , extra_context = None )

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

ModelAdmin.history_view( запрос , object_id , extra_context = None )

Представление 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

Административный JavaScript Django использует библиотеку jQuery .

Чтобы избежать конфликтов с пользовательскими скриптами или библиотеками, jQuery Django (версия 3.5.1) имеет пространство имен как django.jQuery. Если вы хотите использовать jQuery в своем собственном административном JavaScript без включения второй копии, вы можете использовать django.jQueryобъект в списке изменений и добавлять / редактировать представления. Кроме того, ваши собственные формы администратора или виджеты, в зависимости от того, django.jQueryдолжны указываться при объявлении медиаресурсов формы .js=['admin/js/jquery.init.js', …]

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

jQuery был обновлен с 3.4.1 до 3.5.1.

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

Здесь важно использовать a, ModelFormиначе все может сломаться. См. Документацию к формам по настраиваемой проверке и, в частности, заметки о проверке формы модели для получения дополнительной информации.

InlineModelAdminобъекты

класс InlineModelAdmin
класс TabularInline
класс StackedInline

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

from django.db import models

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

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

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

from django.contrib import admin

class BookInline(admin.TabularInline):
    model = Book

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

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

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

InlineModelAdminварианты

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

InlineModelAdminКласс добавляет или подгоняет:

InlineModelAdmin.model

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

InlineModelAdmin.fk_name

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

InlineModelAdmin.formset

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

InlineModelAdmin.form

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

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

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

InlineModelAdmin.classes

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

InlineModelAdmin.extra

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

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

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

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

InlineModelAdmin.max_num

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

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

InlineModelAdmin.min_num

Это контролирует минимальное количество форм, отображаемых в строке. См. modelformset_factory()Дополнительную информацию.

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

InlineModelAdmin.raw_id_fields

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

raw_id_fields- это список полей, которые вы хотите превратить в Inputвиджет для a 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.

Указывает, есть ли у встроенных объектов, которые можно изменить в админке, ссылку на форму изменения. По умолчанию False.

InlineModelAdmin.get_formset( запрос , obj = None , ** kwargs )

Возвращает BaseInlineFormSetкласс для использования в представлениях администратора по добавлению / изменению. objредактируется родительский объект или Noneдобавляется новый родительский объект . См. Пример для ModelAdmin.get_formsets_with_inlines.

InlineModelAdmin.get_extra( запрос , 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( запрос , 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( запрос , obj = None , ** kwargs )

Возвращает минимальное количество встроенных форм для использования. По умолчанию возвращает InlineModelAdmin.min_numатрибут.

Переопределите этот метод, чтобы программно определить минимальное количество встроенных форм. Например, это может быть основано на экземпляре модели (переданном как аргумент ключевого слова obj).

InlineModelAdmin.has_add_permission( запрос , объект )

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

InlineModelAdmin.has_change_permission( запрос , obj = Нет )

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

InlineModelAdmin.has_delete_permission( запрос , obj = Нет )

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

Примечание

objАргумент , передаваемый InlineModelAdminметодов является родительским объектом редактируются или Noneпри добавлении нового родителя.

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

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

from django.db import models

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

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

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

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

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

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

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

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

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

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

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

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

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

from django.db import models

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

from myproject.myapp.models import Image, Product

class ImageInline(GenericTabularInline):
    model = Image

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

admin.site.register(Product, ProductAdmin)

См. Документацию по типам содержимого для получения более подробной информации.

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

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

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

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

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

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

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

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

Если бы мы хотели добавить инструмент в представление списка изменений только для определенной модели с именем «Страница», мы бы скопировали этот же файл в templates/admin/my_app/pageкаталог нашего проекта.

Замещение или замена шаблона администратора

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

Чтобы продолжить приведенный выше пример, мы хотим добавить новую ссылку рядом с Historyинструментом для Pageмодели. Посмотрев на, change_form.html мы определяем, что нам нужно только переопределить object-tools-itemsблок. Поэтому вот наш новый change_form.html:

{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
    <li>
        <a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% translate "History" %}</a>
    </li>
    <li>
        <a href="mylink/" class="historylink">My Link</a>
    </li>
    {% if has_absolute_url %}
        <li>
            <a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% translate "View on site" %}</a>
        </li>
    {% endif %}
{% endblock %}

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

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

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

  • actions.html
  • app_index.html
  • change_form.html
  • change_form_object_tools.html
  • change_list.html
  • change_list_object_tools.html
  • change_list_results.html
  • date_hierarchy.html
  • delete_confirmation.html
  • object_history.html
  • pagination.html
  • popup_response.html
  • prepopulated_fields_js.html
  • search_form.html
  • submit_line.html

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

Примечание

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

Шаблоны root и авторизации

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

Тематическая поддержка

Новое в Django 3.2.

Администратор использует переменные CSS для определения цветов. Это позволяет изменять цвета без необходимости отменять многие отдельные правила CSS. Например, если вы предпочитаете фиолетовый цвет вместо синего, вы можете добавить admin/base.htmlв свой проект переопределение шаблона:

{% extends 'admin/base.html' %}

{% block extrahead %}{{ block.super }}
<style>
:root {
  --primary: #9774d5;
  --secondary: #785cab;
  --link-fg: #7c449b;
  --link-selected-fg: #8f5bb2;
}
</style>
{% endblock %}

Темная тема определяется и применяется в соответствии с медиазапросом prefers-color-scheme .

Список переменных CSS определяется в django/contrib/admin/static/admin/css/base.css.

AdminSiteобъекты

классAdminSite ( имя = 'админ' )

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

Если вы хотите настроить сайт администратора по умолчанию, вы можете переопределить его .

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

AdminSiteатрибуты

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

AdminSite.site_header

Текст, который нужно поместить вверху каждой страницы администратора в виде <h1>(строки). По умолчанию это «Администрирование Django».

AdminSite.site_title

Текст, который нужно поместить в конец каждой страницы администратора <title>(строка). По умолчанию это «Администратор сайта Django».

AdminSite.site_url

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

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

AdminSite.index_title

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

AdminSite.index_template

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

AdminSite.app_index_template

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

AdminSite.empty_value_display

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

AdminSite.enable_nav_sidebar
Новое в Django 3.1.

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

AdminSite.final_catch_all_view
Новое в Django 3.2.

Логическое значение, определяющее, следует ли добавлять последнее всеобъемлющее представление для администратора, которое перенаправляет неаутентифицированных пользователей на страницу входа. По умолчанию установлено значение True.

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

Установка этого Falseне рекомендуется , поскольку в целях защиты от потенциальной модели переписного вопроса о конфиденциальности.

AdminSite.login_template

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

AdminSite.login_form

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

AdminSite.logout_template

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

AdminSite.password_change_template

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

AdminSite.password_change_done_template

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

AdminSiteметоды

AdminSite.each_context( запрос )

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

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

  • 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, delete, и viewразрешение
    • admin_url: URL-адрес списка изменений администратора для модели
    • add_url: URL-адрес администратора для добавления нового экземпляра модели
AdminSite.has_permission( запрос )

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

AdminSite.register( model_or_iterable , admin_class = None , ** параметры )

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

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

AdminSite.unregister( model_or_iterable )

Отменяет регистрацию данного класса модели (или итерации классов).

Повышается, django.contrib.admin.sites.NotRegisteredесли модель еще не зарегистрирована.

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

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

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

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

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

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

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

myapp / admin.py
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)
myproject / urls.py
from django.urls import path

from myapp.admin import admin_site

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

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

Переопределение сайта администратора по умолчанию

Вы можете переопределить значение django.contrib.admin.siteпо умолчанию , установив для default_siteатрибута custom AppConfig значение пути импорта, разделенного точками, либо AdminSiteподкласса, либо вызываемого объекта, который возвращает экземпляр сайта.

myproject / admin.py
from django.contrib import admin

class MyAdminSite(admin.AdminSite):
    ...
myproject / apps.py
from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'myproject.admin.MyAdminSite'
myproject / settings.py
INSTALLED_APPS = [
    ...
    'myproject.apps.MyAdminConfig',  # replaces 'django.contrib.admin'
    ...
]

Несколько административных сайтов в одном URLconf

Вы можете создать несколько экземпляров административного сайта на одном и том же веб-сайте, основанном на Django. Создайте несколько экземпляров AdminSiteи разместите каждый по разному URL-адресу.

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

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

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

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

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

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

Примечание

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

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

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

from django.contrib.auth import views as auth_views

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

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

Наличие указанного admin_password_resetURL-адреса приведет к появлению сообщения «забыли пароль?» Ссылка появится на странице входа администратора по умолчанию под полем пароля.

LogEntryобъекты

класс 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, всегда будут отображаться на том языке, на котором они были зарегистрированы.

Изменение адреса админки

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

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объекта (из приложения опросов) в администраторе по умолчанию, вы должны вызвать:

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

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

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

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

Дополнительные сведения см. В документации по обращению URL-адресов с пространством имен .

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

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

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

displayДекоратор

display( * , boolean = None , ordering = None , description = None , empty_value = None )
Новое в Django 3.2.

Этот декоратор можно использовать для установки определенных атрибутов в пользовательских функциях отображения, которые можно использовать с list_displayили readonly_fields:

@admin.display(
    boolean=True,
    ordering='-publish_date',
    description='Is Published?',
)
def is_published(self, obj):
    return obj.publish_date is not None

Это эквивалентно установке некоторых атрибутов (с оригинальными более длинными именами) непосредственно в функции:

def is_published(self, obj):
    return obj.publish_date is not None
is_published.boolean = True
is_published.admin_order_field = '-publish_date'
is_published.short_description = 'Is Published?'

Также обратите внимание, что empty_valueпараметр декоратора сопоставляется с empty_value_displayатрибутом, назначенным непосредственно функции. Его нельзя использовать вместе с boolean- они исключают друг друга.

Использование этого декоратора не обязательно для создания функции отображения, но может быть полезно использовать его без аргументов в качестве маркера в исходном коде для определения цели функции:

@admin.display
def published_year(self, obj):
    return obj.publish_date.year

В этом случае он не будет добавлять атрибутов к функции.

staff_member_requiredДекоратор

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

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

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

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

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

@staff_member_required
def my_view(request):
    ...

Copyright ©2021 All rights reserved