Продолжаем начатое в первой части учебника. Мы продолжим разрабатывать приложение для голосования и создадим интерфейс администратора.
Философия
Создание интерфейса администратора для добавления, изменения и удаления содержимого сайта – в основном скучная не креативная задача. Django значительно автоматизирует и упрощает эту задачу.
Django создавался для новостных сайтов, у которых есть разделение между публичными страницами и интерфейсом администратора. Менеджеры используют последний для добавления новостей и другого содержимого сайта, это содержимое отображается на сайте. Django позволяет легко создать универсальный интерфейс для редактирования содержимого сайта.
Интерфейс администратора не предназначен для использования пользователями. Он создан для менеджеров и администраторов сайта.
Первым делом необходимо создать пользователя, который может заходить на интерфейс администратора. Выполните следующую команду:
$ python manage.py createsuperuser
Введите имя пользователя и нажмите Enter.
Username: admin
Теперь введите email:
Email address: admin@example.com
И наконец введите пароль.
Password: **********
Password (again): *********
Superuser created successfully.
Интерфейс администратора включен по умолчанию. Давайте запустим встроенный сервер для разработки и посмотрим на него.
Напомним, что сервер для разработки запускается следующим образом:
$ python manage.py runserver
Откроем “/admin/” локального домена в браузере – например, http://127.0.0.1:8000/admin/. Вы должны увидеть страницу авторизации интерфейса администратора:
Т.к. translation включен по умолчанию, страница авторизации может быть на вашем родном языке, зависит от настроек браузера и наличия перевода для вашего языка.
Не совпадает с тем, что вы видите?
Если вместо страницы авторизации вы получили ошибку:
ImportError at /admin/
cannot import name patterns
...
значит вы используете неверную версию Django. Смотрите учебник для используемой версии или обновите Django.
Теперь попробуйте войти в админку. Вы должны видеть следующую страницу Django:
Вы должны увидеть несколько разделов: группы и пользователи. Они предоставлены приложением авторизации Django django.contrib.auth.
А где же наше приложение голосования? Оно не отображается в интерфейсе администратора.
Нам нужно указать, что объекты модели Question могли редактироваться в интерфейсе администратора. Для этого создадим файл polls/admin.py, и отредактируем следующим образом:
from django.contrib import admin
from .models import Question
admin.site.register(Question)
После регистрации модели Question Django отобразит ее на главной странице:
Нажмите “Questions”. Вы попали на страницу “списка объектов” для голосований. Эта страница содержит все объекты из базы данных и позволяет выбрать один из них для редактирования. Мы видим голосование “What’s up?”, которое создали в первой части учебника:
Нажмите “What’s up?” чтобы отредактировать его:
Заметим:
Поля формы формируются на основе описания модели Question.
Для различных типов полей модели (DateTimeField, CharField) используются соответствующие HTML поля. Каждое поле знает как отобразить себя в интерфейсе администратора.
К полям DateTimeField добавлен JavaScript виджет. Для даты добавлена кнопка “Сегодня” и календарь, для времени добавлена кнопка “Сейчас” и список распространенных значений.
В нижней части страницы мы видим несколько кнопок:
Save – сохранить изменения и вернуться на страницу списка объектов.
Save and continue editing – сохранить изменения и снова загрузить страницу редактирования текущего объекта.
Save and add another – Сохранить изменения и перейти на страницу создания нового объекта.
Delete – Показывает страницу подтверждения удаления.
Если значение “Date published” не совпадает с временем создания объекта в первой части учебника, возможно, вы неверно определили настройку TIME_ZONE. Измените ее и перезагрузите страницу.
Измените “Date published”, нажав “Today” и “Now”. Затем нажмите “Save and continue editing.” Теперь нажмите “History” в правом верхнем углу страницы. Вы увидите все изменения объекта, сделанные через интерфейс администратора, время изменений и пользователя, который их сделал:
Потратим несколько минут, чтобы полюбоваться кодом, который нам не пришлось писать самостоятельно. После регистрации модели Question, используя admin.site.register(Question), Django создал форму для модели. Скорее всего, вам захочется изменить ее. Вы можете это сделать, используя параметры при регистрации модели.
Вот как это работает. Давайте поменяем порядок полей в форме. Замените admin.site.register(Question) на:
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
admin.site.register(Question, QuestionAdmin)
Создаем объект ModelAdmin и предаем его в admin.site.register().
Теперь поле “Publication date” отображается перед полем “Question”:
Для нескольких полей это выглядит не очень внушительно, но при большом количестве полей порядок может значительно повысить удобство.
Для форм с большим количеством полей можно разбить форму на группу полей:
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 – название группы полей. Вот как будет выглядеть наша форма:
Вы можете добавить HTML классы для каждой группы полей. Django предоставляет класс "collapse", который отображает группу полей изначально скрытой. Это полезно, если форма содержит поля, которые редко редактируются:
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
admin.site.register(Question, QuestionAdmin)
Теперь, когда страница добавления/редактирования вопроса выглядит хорошо, давай улучшим страницу отображения списка вопросов.
Вот как она выглядит сейчас:
По умолчанию Django отображает результат выполнения str() для каждого объекта. Но чаще всего хочется показывать список полей. Для этого используйте параметр list_display, который является кортежем состоящим из названий полей модели:
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date')
Для примера давайте еще и добавим метод was_published_recently из Части 1 учебника:
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date', 'was_published_recently')
Теперь страница списка вопросов выглядит следующим образом:
Вы можете нажать на заголовок колонки чтобы отсортировать записи по полю – но не для was_published_recently, так как сортировка по методу не поддерживается. Название колонки для was_published_recently по умолчанию равно названию метода (нижние подчеркивание заменяется на пробелы), а значение равно строковому представлению результата выполнения метода.
Вы можете исправить это, добавив несколько атрибутов (в polls/models.py) этому методу:
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
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 снова и добавим на страницу списка вопросов Фильтры, используя list_filter. Добавьте следующую строку в QuestionAdmin:
list_filter = ['pub_date']
Это добавляет “Фильтр” по полю pub_date в боковой панели:
Тип фильтра зависит от типа поля. Так как pub_date является DateTimeField, Django отображает соответствующие варианты для фильтрации: “Any date,” “Today,” “Past 7 days,” “This month,” “This year.”
Теперь добавим поиск:
search_fields = ['question_text']
Это добавляет поле для поиска в верхней части страницы. При вводе запроса, Django будет искать по полю question_text. Вы можете использовать любое количество полей – учтите что используется запрос LIKE, так что постарайтесь не перегрузить вашу базу данных.
Страница списка объектов также содержит постраничное отображение. По умолчанию отображается 100 объектов на страницу. Поменять количество объектов на одной странице, поля для поиска, фильтры, добавить иерархию по дате и отображаемые поля - все это возможно.
“Django administration” в “шапке” страницы выглядит нелепо. Это просто замещающий текст.
Его очень легко заменить, используя систему шаблонов Django. Интерфейс администратора работает благодаря Django и использует систему шаблонов Django.
Создайте каталог templates в каталоге проекта (который содержит manage.py). Шаблоны могут располагаться где угодно, главное чтобы Django имел доступ к ним. (Django запускается под пользователем, под которым запущен сервер.) Но мы советуем располагать шаблоны внутри проекта.
Откройте файл настроек (напомним это mysite/settings.py) и найдите опцию DIRS в настройке TEMPLATES:
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 будет искать шаблоны.
Теперь создайте каталог admin в каталоге templates, и скопируйте шаблон admin/base_site.html из встроенных шаблонов в исходниках Django (django/contrib/admin/templates) в этот каталог.
Где лежит исходный код Django?
Если вы не знаете где лежат исходники Django, выполните следующую команду:
$ python -c "
import sys
sys.path = sys.path[1:]
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. При выполнении шаблона admin/base_site.html Django создаст HTML страницу. Не волнуйтесь если ничего не понимаете в этом – в шаблонах Django мы разберемся в Части 3.
Любой шаблон интерфейса администратора можно переопределить. Чтобы переопределить шаблон, сделайте тоже что и с base_site.html – скопируйте его в каталог с шаблонами проекта и внесите изменения.
Внимательные читатели спросят: если DIRS пустая по умолчанию, как Django находит шаблоны интерфейса администратора по умолчанию? Т.к. APP_DIRS по умолчанию True, Django пытается найти шаблон в подкаталоге templates/ каждого приложении, если шаблон не найден другим способом (не забываем, что django.contrib.admin – это приложение).
Наше приложение простое и не требует переопределения шаблонов. Но если оно станет большим и сложным, и нам понадобится изменить его шаблоны, логичнее изменить шаблоны для приложения, а не для проекта. В таком случае вы сможете добавить приложения для голосования в любой проект и переопределенные шаблоны будут работать.
Смотрите раздел о загрузке шаблонов, чтобы узнать, как Django ищет шаблоны.
Возможно, вам понадобится настроить главную страницу интерфейса администратора.
По умолчанию она показывает все приложения в алфавитном порядке из настройки INSTALLED_APPS, которые зарегистрированы в интерфейсе администратора. Главная страница очень важна и должна быть удобной.
Для главной страницы используется шаблон admin/index.html. (Сделайте тоже что и с шаблоном admin/base_site.html из раздела выше – скопируйте его из приложения Django в каталог шаблонов проекта.) Откройте файл и вы увидите использование переменной app_list. Эта переменная содержит все отображаемые приложения. Вместо нее вы можете явно указать ссылки на нужные страницы. Опять же, не волнуйтесь что вы ничего не понимаете, шаблоны будут обсуждаться в Части 3.
Если вы освоили интерфейс администратора, переходите к третьей части этого учебника.
Jun 02, 2016