Создание первого приложения на Django, часть 7

This tutorial begins where Tutorial 6 left off. We’re continuing the web-poll application and will focus on customizing Django’s automatically-generated admin site that we first explored in Tutorial 2.

Где получить помощь:

Если у вас возникли проблемы с просмотром этого учебника, перейдите в раздел Получение справки FAQ.

Настройка админки

Зарегистрировав модель Question в admin.site.register (Question), Django смог построить представление формы по умолчанию. Предполагаем, что вы захотите настроить внешний вид админки сами. Это можно сделать, передав Django нужные параметры при регистрации объекта.

Давайте посмотрим, как это работает, переупорядочив поля в форме редактирования. Замените строку admin.site.register(Question) на:

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

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

Это конкретное изменение приводит к тому, что «Дата публикации» предшествует полю «Вопрос»:

Fields have been reordered

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

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

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

Первый элемент каждого кортежа в fieldsets - это заголовок набора полей. Вот как выглядит наша форма сейчас:

Form has fieldsets now

Настройка страницы списка объектов

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

Вот как это выглядит на данный момент:

Polls change list page

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

polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ['question_text', 'pub_date']

Просто для примера давайте включим метод was_published_recently() из Части 2:

polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ['question_text', 'pub_date', 'was_published_recently']

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

Polls change list page, updated

Вы можете щелкнуть заголовки столбцов, чтобы отсортировать по этим значениям - за исключением случая заголовка was_published_recently, потому что сортировка по выводу произвольного метода не поддерживается. Также обратите внимание, что заголовок столбца для was_published_recently по умолчанию является именем метода (с подчеркиванием, замененным пробелами), и что каждая строка содержит строковое представление выходных данных.

You can improve that by using the display() decorator on that method (in polls/models.py), as follows:

polls/models.py
from django.contrib import admin

class Question(models.Model):
    # ...
    @admin.display(
        boolean=True,
        ordering='pub_date',
        description='Published recently?',
    )
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now

For more information on the properties configurable via the decorator, see list_display.

Снова отредактируйте ваш файл polls/admin.py и добавьте улучшение на страницу списка изменений Question: фильтры с использованием list_filter. Добавьте следующую строку в QuestionAdmin

list_filter = ['pub_date']

Это добавляет боковую панель «Фильтр», которая позволяет фильтровать список изменений по полю pub_date:

Polls change list page, updated

Тип отображаемого фильтра зависит от типа поля, по которому вы фильтруете. Поскольку pub_date является DateTimeField, Django знает, как задать соответствующие параметры фильтра: «Любая дата», «Сегодня», «Прошлые 7 дней», «Этот месяц», «В этом году».

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

search_fields = ['question_text']

Это добавляет окно поиска в верхней части списка изменений. Когда кто-то вводит условия поиска, Django будет искать в поле question_text. Вы можете использовать столько полей, сколько захотите - хотя, поскольку он использует закулисный запрос LIKE, ограничение числа полей поиска до разумного числа облегчит поиск в вашей базе данных.

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

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

Очевидно, что видеть «Django administration» в верхней части каждой страницы администратора нелепо. Это просто текст-заглушка.

Это легко изменить, используя систему шаблонов Django. Администратор Django работает на основе самого Django, а его интерфейсы используют собственную систему шаблонов Django.

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

Создайте каталог templates в каталоге вашего проекта (тот, который содержит manage.py). Шаблоны могут находиться в любой точке вашей файловой системы, к которой имеет доступ Django. (Django работает от имени любого пользователя, работающего на вашем сервере.) Однако, размещение шаблонов в проекте является хорошим соглашением.

Откройте файл настроек (mysite/settings.py, запомните) и добавьте параметр DIRS в настройку TEMPLATES:

mysite/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

DIRS - список каталогов файловой системы, которые нужно проверить при загрузке шаблонов Django; это путь поиска.

Организация шаблонов

Как и в случае со статическими файлами, мы можем собрать все наши шаблоны в одном большом каталоге шаблонов, и он будет отлично работать. Однако шаблоны, которые принадлежат конкретному приложению, должны быть размещены в каталоге шаблонов этого приложения (например, polls/templates), а не в каталоге проекта (templates). Мы обсудим более подробно в учебнике повторно используемые приложения почему мы делаем это.

Now create a directory called admin inside templates, and copy the template admin/base_site.html from within the default Django admin template directory in the source code of Django itself (django/contrib/admin/templates) into that directory.

Где находятся исходные файлы Django?

Если вам сложно определить, где находятся исходные файлы Django в вашей системе, выполните следующую команду:

$ python -c "import django; print(django.__path__)"
...\> py -c "import django; print(django.__path__)"

Затем просто отредактируйте файл и замените {{ site_header|default:_ ('Django administration') }} (включая фигурные скобки) именем вашего собственного сайта, как вы считаете нужным. Вы должны получить код, подобный следующему:

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

Мы используем этот подход, чтобы научить вас переопределять шаблоны. В реальном проекте вы, вероятно, использовали бы атрибут django.contrib.admin.AdminSite.site_header, чтобы упростить эту настройку.

Этот файл шаблона содержит много текста, такого как {% block branding %} и {{ title }}. Теги {% и {{ являются частью языка шаблонов Django. Когда Django отображает admin/base_site.html, этот язык шаблонов будет обработан для создания окончательной HTML-страницы, как мы видели в Части 3 учебника.

Обратите внимание, что любой из стандартных шаблонов администратора Django может быть переопределен. Чтобы переопределить шаблон, просто сделайте то же самое, что вы сделали с base_site.html - скопируйте его из каталога по умолчанию в ваш пользовательский каталог и внесите изменения.

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

Проницательные читатели спросят: если DIRS было пусто по умолчанию, как Django находил шаблоны администратора по умолчанию? Ответ таков: поскольку APP_DIRS установлен в True, Django автоматически ищет подкаталог templates/ в каждом пакете приложения для использования в качестве запасного варианта (не забывайте, что django.contrib.admin является приложением).

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

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

Настройка главной страницы админки

Аналогично вы можете настроить внешний вид главной страницы админки Django.

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

Шаблон для настройки - admin/index.html. (Сделайте то же самое, что и с admin/base_site.html в предыдущем разделе - скопируйте его из каталога по умолчанию в каталог пользовательских шаблонов). Отредактируйте файл, и вы увидите, что он использует переменную шаблона с именем app_list. Эта переменная содержит все установленные приложения Django. Вместо этого вы можете жестко закодировать ссылки на специфичные для объекта страницы администратора любым удобным для вас способом.

Что дальше?

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

Если вы знакомы с пакетами Python и хотите узнать, как превратить опросы в «повторно используемое приложение», ознакомьтесь с Расширенное руководство: как писать повторно используемые приложения.

Вернуться на верх