Сайт администрирования 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.contrib.auth.context_processors.auth , django.contrib.messages.context_processors.request и django.contrib.messages.context_processors.messages в 'context_processors' опции OPTIONS .

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

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

  3. Если вы настроили настройку MIDDLEWARE , так django.contrib.auth.middleware.AuthenticationMiddleware и django.contrib.messages.middleware.MessageMiddleware должно быть.

  4. Включите URL-адреса администратора в конфигурацию URL-адресов .

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

Если вам нужно создать пользователя для входа, используйте команду createsuperuser . По умолчанию для подключения к сайту администрирования требуется, чтобы один из атрибутов is_superuser или 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' на 'django.contrib.admin.apps.SimpleAdminConfig' в настройке 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')

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

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

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

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

from django.db import models

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

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

from django.contrib import admin

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

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

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

ModelAdmin.fields

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

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

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

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

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

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

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

Заметка

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

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

ModelAdmin.fieldsets

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

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

Двоичные кортежи имеют формат , где - строка, представляющая заголовок группы полей, и словарь информации о группе полей, включая список полей для отображения внутри.(nom, options_champs) nom options_champs

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

from django.contrib import admin

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

В результате открывается страница администрирования, которая выглядит так:

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

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

Словарь field_options может содержать следующие ключи:

  • fields

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

    Пример:

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

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

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

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

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

  • classes

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

    Пример:

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

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

  • description

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

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

ModelAdmin.filter_horizontal

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

Заметка

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

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

class PersonForm(forms.ModelForm):

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

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

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

ModelAdmin.formfield_overrides

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

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

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

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

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

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

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

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

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

ModelAdmin.inlines

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

ModelAdmin.list_display

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

Пример:

list_display = ('first_name', 'last_name')

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

list_display может содержать четыре разных типа значений:

  • Имя поля шаблона. Например :

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

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

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

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        def decade_born_in(self):
            return self.birthday.strftime('%Y')[:3] + "0's"
        decade_born_in.short_description = 'Birth decade'
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'decade_born_in')
    

Некоторые особые случаи, о которых следует сообщить list_display :

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

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

  • Если поле равно единице BooleanField , Django отображает красивый активный / неактивный значок вместо значений True или False .

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

    Вот полный образец модели:

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

  • Если значением поля является None пустая строка или пустая итерация, Django отобразит - (прочерк). Вы можете изменить это с помощью AdminSite.empty_value_display :

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

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

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

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

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

    Вот полный образец модели:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        def born_in_fifties(self):
            return self.birthday.strftime('%Y')[:3] == '195'
        born_in_fifties.boolean = True
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'born_in_fifties')
    
  • Этот метод __str__() так же применим, list_display как и любой другой модельный метод, поэтому совершенно правильно написать:

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

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

    Например :

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

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

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

    colored_first_name.admin_order_field = '-first_name'
    

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

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

    Эти выражения запроса могут быть использованы admin_order_field . например

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

    Например :

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        def my_property(self):
            return self.first_name + ' ' + self.last_name
        my_property.short_description = "Full name of the person"
        my_property.admin_order_field = 'last_name'
    
        full_name = property(my_property)
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('full_name',)
    
  • Имена полей в list_display также появляются как классы CSS в выводе HTML, как и colonne-<nom_de_champ> в каждом элементе <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),
        )
    

    Заметка

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

    Новое в 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 к критериям сортировки, если он не находит поле или набор полей, гарантирующих уникальную сортировку.

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

ModelAdmin.paginator

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

ModelAdmin.prepopulated_fields

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

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

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

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

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

ModelAdmin.preserve_filters

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

ModelAdmin.radio_fields

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

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

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

radio_fields Включайте поле, только если оно является полем ForeignKey или его атрибут choices установлен.

ModelAdmin.autocomplete_fields

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ModelAdmin.raw_id_fields

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

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

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

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

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

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

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

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

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

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

    def address_report(self, instance):
        # assuming get_full_address() returns a list of strings
        # for each line of the address and you want to separate each
        # line by a linebreak
        return format_html_join(
            mark_safe('<br>'),
            '{}',
            ((line,) for line in instance.get_full_address()),
        ) or mark_safe("<span class='errors'>I can't determine this address.</span>")

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

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

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

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

ModelAdmin.save_as_continue

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

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

ModelAdmin.save_on_top

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

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

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

ModelAdmin.search_fields

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

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

search_fields = ['foreign_key__related_fieldname']

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

search_fields = ['user__email']

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

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

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

Имейте в виду, что из-за расстановки переносов в поисковых запросах, которые затем комбинируются с, AND как объяснялось ранее, поиск exact работает только с одним поисковым словом, поскольку не все два или более слов могут быть точными совпадениями (кроме если все слова совпадают).

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

Префикс Запрос
^ startswith
знак равно iexact
@ search
Любой) icontains

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

ModelAdmin.show_full_result_count

Определите, show_full_result_count чтобы определить, должно ли общее количество объектов отображаться на отфильтрованной странице администратора (например ). Если для этого параметра установлено значение , вместо него отображается текст в стиле .99 résultats (103 au total) False 99 résultats (tout afficher)

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

ModelAdmin.sortable_by

По умолчанию на странице списка изменений разрешена сортировка по всем полям модели (и исполняемым объектам, имеющим свойство 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 изменяет список отображаемых объектов на основе тех, которые соответствуют указанному поисковому запросу. Он принимает HTTP-запрос, набор запросов, который применяет общие фильтры и поисковый запрос, предоставленный пользователем. Он возвращает кортеж, содержащий измененный набор запросов для применения поиска, а также логическое значение, указывающее, могут ли результаты содержать дубликаты.

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

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 в форме добавления); предполагается, что он вернет словарь, как описано выше в разделе 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 и должен возвращать логическое значение или список 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( запрос , объект )
Новое в Django 3.0.

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

ModelAdmin.get_urls()

Метод get_urls on one ModelAdmin возвращает URL-адреса, которые будут использоваться для этого, так ModelAdmin же, как и конфигурация URL-адресов. Следовательно, вы можете дополнить их, как описано в разделе Распространение 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 используемый в форме, установленной на странице списка для модификации. Чтобы использовать настраиваемую форму, например:

from django import forms

class MyForm(forms.ModelForm):
    pass

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

Заметка

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

ModelAdmin.get_changelist_formset( просьба , ** 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( поиск , значение )

Объекты на странице списка для модификации интерфейса администрирования могут быть отфильтрованы по поисковым выражениям из строки запроса GET 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 one 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 .

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

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

Точка входа для настройки процесса удаления из поля зрения delete_view() и « Действие » для удаления выбранных элементов ».

Параметр objs представляет собой серию однородных объектов (один QuerySet или список экземпляров модели) для удаления и request является запросом HttpRequest .

Этот метод должен возвращать 4 кортежа .(objets_supprimés, nombre_de_modèles, permissions_nécessaires, protégés)

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

nombre_de_modèles представляет собой словарь соответствия между атрибутом verbose_name_plural каждой модели и количеством объектов, которые необходимо удалить из этой модели.

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

protégés - это список строк, представляющих все защищенные связанные объекты, которые нельзя удалить. Список отображается в шаблоне.

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

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 3.0:

Встроенная версия jQuery обновлена ​​с 3.3.1 до 3.4.1.

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

Встроенная версия jQuery обновлена ​​с 3.4.1 до 3.5.1.

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

Django предоставляет как несжатые, так и "свернутые" версии jQuery, как jquery.js и jquery.min.js соответственно.

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

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

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

class ArticleAdmin(admin.ModelAdmin):
    form = MyArticleAdminForm

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

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

Здесь важно использовать один ModelForm , иначе что-то может пойти не так. Обратитесь к документации , образует в пользовательской проверку и более конкретно, заметки о проверке модельных форм для получения дополнительной информации.

Объекты InlineModelAdmin

класс 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 будьте осторожны при написании кода проверки, основанного на функциональности родительской модели. Если последнее не удается во время проверки, его содержимое может находиться в несогласованном состоянии, как описано в предупреждении Validate ModelForm .

InlineModelAdmin.classes

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

InlineModelAdmin.extra

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

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

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

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

InlineModelAdmin.max_num

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

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

InlineModelAdmin.min_num

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

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

InlineModelAdmin.raw_id_fields

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

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

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

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

InlineModelAdmin.verbose_name

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

InlineModelAdmin.verbose_name_plural

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

InlineModelAdmin.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 , вам необходимо явно указать внешний ключ, поскольку Django не может сделать это автоматически:

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 помощью параметра поля 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/ проекта и внести необходимые изменения.

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

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

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

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

Шаблоны рута и подключения

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

Объекты 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``n'est pas défini à autre chose que ``/

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.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 в конфигурации URL

Последним шагом в настройке администрирования Django является включение вашего экземпляра AdminSite в конфигурацию URL. Для этого укажите указанный 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 вместо того, чтобы делать это на сайте по умолчанию. Наконец, обновите, monprojet/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 из каждого приложения в основной модуль projet.admin . Это означает , что необходимо заменить 'django.contrib.admin' с 'django.contrib.admin.apps.SimpleAdminConfig' в настройках INSTALLED_APPS .

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

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

myproject / admin.py
from django.contrib import admin

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

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

Несколько сайтов администрирования в одной конфигурации URL

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

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

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

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

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

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

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

Заметка

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

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

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

from django.contrib.auth import views as auth_views

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

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

Присутствие указанного URL-адреса admin_password_reset приведет к появлению ссылки «Забыли пароль?». ”На странице входа администратора по умолчанию под полем для ввода пароля.

Объекты LogEntry (логирование)

класс models.LogEntry

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

Атрибуты LogEntry

LogEntry.action_time

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

LogEntry.user

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

LogEntry.content_type

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

LogEntry.object_id

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

LogEntry.object_repr

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

LogEntry.action_flag

Тип действия вошли: ADDITION , CHANGE , DELETION .

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

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

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

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

Методы LogEntry

LogEntry.get_edited_object()

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

LogEntry.get_change_message()

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

Обратное разрешение админских URL

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

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

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

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

страница Имя URL настройки
Список для редактирования {{ étiquette_app }}_{{ nom_modèle }}_changelist  
Добавление {{ étiquette_app }}_{{ nom_modèle }}_add  
исторический {{ étiquette_app }}_{{ nom_modèle }}_history object_id
делеция {{ étiquette_app }}_{{ nom_modèle }}_delete object_id
модификация {{ étiquette_app }}_{{ nom_modèle }}_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 при вызове reverse . Например, если вы специально хотите получить административное представление именованного административного экземпляра custom , вы должны написать:

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

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

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

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

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

Декоратор staff_member_required

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

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

  • Если пользователь вошел в систему, является членом author ( User.is_staff=True ) и active ( 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 ©2020 All rights reserved