Написание вашего первого приложения 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 administration» вверху каждой страницы админки — абсурд. Это просто текст-заполнитель.
Однако вы можете изменить это, используя систему шаблонов 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 админки для некоторых его функций, было бы разумнее изменить шаблоны приложения, а не проекта. Таким образом, вы могли бы включать приложение опросов в любой новый проект и быть уверены, что оно найдёт необходимые настраиваемые шаблоны.
См. документацию по загрузке шаблонов для получения дополнительной информации о том, как 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/5.2/intro/tutorial07/