Создание первого приложения Django, часть 7
Это руководство продолжает тему, на которой мы остановились в руководстве 6. Мы продолжим работу над веб-приложением для опросов и сосредоточимся на настройке автоматически созданного сайта администрирования Django, с которым мы впервые познакомились в руководстве 2.
Где получить помощь:
Если у вас возникли трудности при прохождении этого руководства, обратитесь к разделу Получение помощи в FAQ.
Настройка формы администрирования
Зарегистрировав модель Question в admin.site.register(Question), Django смог создать представление формы по умолчанию. Часто возникает необходимость настроить внешний вид и работу формы администрирования. Для этого нужно указать Django нужные параметры при регистрации объекта.
Давайте посмотрим, как это работает, изменив порядок полей в форме редактирования. Замените строку admin.site.register(Question) на:
polls/admin.pyfrom 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.pyfrom 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.pyclass QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ["question_text", "pub_date"]
Для полноты картины добавим также метод was_published_recently() из руководства 2:
polls/admin.pyclass QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ["question_text", "pub_date", "was_published_recently"]
Теперь страница списка вопросов выглядит так:
Вы можете щёлкнуть заголовок столбца, чтобы отсортировать список по соответствующим значениям, — за исключением заголовка was_published_recently, поскольку сортировка по результату произвольного метода не поддерживается. Также обратите внимание, что заголовком столбца was_published_recently по умолчанию служит имя метода (подчёркивания заменяются пробелами), а в каждой строке отображается строковое представление результата.
Это можно улучшить, добавив к методу декоратор display() (изменив файл polls/models.py, созданный в руководстве 2), например так:
polls/models.pyfrom 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:
Тип отображаемого фильтра зависит от типа поля, по которому выполняется фильтрация. Поскольку pub_date — это DateTimeField, Django подбирает подходящие варианты фильтрации: «Любая дата», «Сегодня», «За последние 7 дней», «В этом месяце», «В этом году».
Всё выглядит хорошо. Давайте добавим возможность поиска:
search_fields = ["question_text"]
В верхней части списка объектов появится поле поиска. Когда пользователь вводит поисковый запрос, Django выполняет поиск по полю question_text. Можно указать сколько угодно полей, но поскольку за кулисами выполняется запрос LIKE, разумное количество полей поиска упростит работу базы данных.
Заодно отметим, что списки объектов поддерживают постраничную навигацию. По умолчанию на каждой странице отображается 100 элементов. Параметры Change list pagination, search boxes, filters, date-hierarchies и column-header-ordering работают вместе именно так, как и ожидается.
Настройка внешнего вида администрирования
Очевидно, что надпись «Администрирование Django» в верхней части каждой страницы администрирования выглядит нелепо. Это всего лишь текст-заполнитель.
Однако её можно изменить с помощью системы шаблонов Django. Администрирование Django работает на самом Django, а его интерфейсы используют собственную систему шаблонов Django.
Настройка шаблонов проекта
Создайте каталог templates в каталоге djangotutorial. Шаблоны могут находиться в любом месте файловой системы, доступном Django. (Django работает от имени того же пользователя, что и сервер.) Однако хорошей практикой считается хранить шаблоны внутри проекта.
Откройте файл настроек (не забудьте, что это mysite/settings.py) и добавьте параметр DIRS в настройку TEMPLATES:
mysite/settings.pyTEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"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 %}
<div id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></div>
{% if user.is_anonymous %}
{% include "admin/color_theme_toggle.html" %}
{% endif %}
{% 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. Вместо неё вы можете задать ссылки на страницы администрирования отдельных объектов любым удобным способом.
Когда освоитесь с администрированием, прочитайте часть 8 этого руководства, чтобы узнать, как использовать сторонние пакеты.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/intro/tutorial07/