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

Этот учебник начинается с того места, где мы остановились в Tutorial 6. Мы продолжаем работу над приложением web-poll и сосредоточимся на настройке автоматически генерируемого администратором сайта Django, который мы впервые рассмотрели в Tutorial 2.

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

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

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

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

Вы можете улучшить это, используя декоратор display() в этом методе (в polls/models.py) следующим образом:

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

Для получения дополнительной информации о свойствах, настраиваемых с помощью декоратора, смотрите 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 элементов на странице. Изменить нумерацию, поля поиска, filters, по дате и :attr:`сортировка по заголовкам <django.contrib.admin.ModelAdmin.list_display>`all работать вместе, как вы думаете, они должны.

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

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

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

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

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

Откройте файл настроек (mysite/settings.py, запомните) и добавьте параметр DIRS <TEMPLATES-DIRS> настройку :setting:`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). Мы обсудим более подробно в учебнике многоразовые приложения почему мы делаем это.

Теперь создайте каталог с именем admin внутри templates и скопируйте шаблон admin/base_site.html из директории шаблона администратора Django по умолчанию в исходном коде самого Django (django/contrib/admin/templates) в этот каталог.

Где находятся исходные файлы 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 и хотите узнать, как превратить опросы в «повторно используемое приложение», ознакомьтесь с Расширенное руководство: как писать повторно используемые приложения.

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