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

В прошлый раз мы закончили изучение основ Джанго на Шестой части учебника, где разобрались как использовать статические файлы в Django. Мы продолжаем приложение Web-poll и сконцентрируемся на настройке автоматически сгенерированного админ-сайта Django, который мы впервые изучили в Части 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() - в любое время, когда вам нужно изменить параметры администратора для модели.

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

Поля были упорядочены

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

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

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

Форма теперь имеет наборы полей

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

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

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

Опросы изменяют страницу списка

По умолчанию 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')

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

Обновлена страница списка изменений в опросах

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

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

polls/models.py
class Question(models.Model):
    # ...
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

Для получения дополнительной информации об этих свойствах метода см. list_display.

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

list_filter = ['pub_date']

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

Обновлена страница списка изменений в опросах

Тип отображаемого фильтра зависит от типа поля, по которому вы фильтруете. Поскольку 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': [os.path.join(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 и хотите узнать, как превратить опросы в «повторно используемое приложение», ознакомьтесь с Расширенное руководство: как писать повторно используемые приложения.

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