Предыдущая часть – Django: пример создания приложения – часть 2: создание и работа с database API
Содержание
Создание суперпользователя
Для начала – нам необходимо создать пользователя, который сможет входить в админпанель.
Выполните следующую команду:
$ python manage.py createsuperuser Username (leave blank to use 'setevoy'): Email address: [email protected] Password: Password (again): Superuser created successfully.
Запуск сервера разработки
Админпанель Django активирована по умолчанию. Давайте запустим сервер разработки и посмотрим её:
$ python manage.py runserver 77.***.***.20:8000
Теперь – откройте браузер, и перейдите по адресу http://ваш_IP:8000/admin/. Вы должны увидеть окно входа в панель управления:
Теперь – войдите в панель управления, используя логин и пароль, которые вы создали в начале. Вы должны увидеть главную страницу панели управления:
Вы должны увидеть две группы содержимого, доступного для редактирования – Группы (Groups) и Пользователи (Users). Они предоставляются фреймворком авторизации django.contrib.aut
h.
Добавление приложения в админпанель
Сейчас ваше приложение – Question
– не отображается в панели управления.
Что бы добавить его туда – нам необходимо указать админпанели, что приложение Questions
тоже имеет интерфейс администрирования. Что бы сделать это – отредактируйте файл polls/admin.py
в который добавьте такой код:
from django.contrib import admin from .models import Question admin.site.register(Question)
Обзор функционала панели управления
Теперь, когда мы зарегистрировали Questions
, обновите страницу админпанели – в ней появится новый блок:
Нажмите на “Questions” – и вы попадёте в “список изменений” (change list) для ваших вопросов.
Тут отображаются все созданные вами вопросы из базы данных, и можно выбрать какой из них редактировать. Вот вопрос “What’s up?”, который создали в предыдущей части:
Нажмите на него для редактирования:
Вот на что тут стоит обратить внимание:
- форма сгенерирована автоматически из модели
Question
; - различные типы данных модели (
DateTimeField
,CharField
) соответствуют подходящему HTML-виджету ввода данных ; каждый тип данных знает, как ему отобразить себя в панели управления Django; - каждый элемент
DateTimeField
имеет JavaScript ссылку; у дат есть ссылка Today и всплывающее окно календаря, а у поля времени – ссылка “сейчас” и всплывающее окно с наиболее используемыми временными данными.
Нижняя часть страницы предоставляет вам такие опции:
- Save – сохранить изменения и вернуться на предыдущую страницу к списку изменений;
- Save and continue editing – сохранить изменения, и перезагрузить страницу редактируемого объекта;
- Save and add another – сохранить изменения, и загрузить новую пустую страницу для создания аналогичного объекта;
- Delete – отобразит страницу подтверждения удаления.
Измените “Date published“, кликнув на Today и Now. Затем – нажмите Save and continue editing,а потом – History, справа вверху. Вы увидите страницу, на которой будут отображены все изменения, сделанные с этим объектом через панель управления Django, с указанием времени и имени пользователя, который их выполнил:
Изменение отображения форм в админпанели
Задумайтесь на минуту – написания какого количества кода вам удалось избежать. После регистрации 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()
.
В данном случае мы изменили порядок отображения – теперь 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)
Добавление связанных объектов
ОК, у нас есть страничка Question в панель и управления. Но у Question – есть множественные Choices (варианты ответов), и админпанель их пока не отображает.
Есть два способа решить эту задачу. Первый – просто зарегистрировать Choice
, как мы это сделали с Question
– в файле polls/admin.py
:
from django.contrib import admin from .models import Choice, Question class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] admin.site.register(Question, QuestionAdmin) admin.site.register(Choice)
Теперь Choice доступны в панели управления:
В этой форме поле Question – выпадающий список, содержащий все вопросы в базе данных. Django знает, что ForeignKey
должно представляться в админпанели как форма <select>
. В нашем случае – имеется только один вопрос.
Обратите так же внимание на +, который является ссылкой на добавление нового вопроса. Если вы нажмёте на Add Another Question – у вас появится всплывающее окно с формой добавления нового вопроса. Если вы добавите тут новый вопрос – Django сохранит его в базе, и добавит к списку доступных вопросов.
Однако, это неэффективный способ вариантов ответов в систему. Было бы лучше, если бы вы могли создавать несколько Choice непосредственно во время создания объекта Question
. Давайте реализуем это.
Удалите admin.site.register(Choice)
из файла polls/admin.py
, и отредактируйте код Question
:
from django.contrib import admin from .models import Choice, Question class ChoiceInline(admin.StackedInline): model = Choice extra = 3 class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] admin.site.register(Question, QuestionAdmin)
Этот код указывает Django следующее: “Объекты Choice могут редактироваться из панели управления Question . По умолчанию – предоставить 3 поля для вариантов ответа“.
Перейдите на страницу Add question и посмотрите – как это будет выглядеть:
Вот как это работает: у нас есть три слота для связанных Choice
– как указано параметром extra
– и каждый раз, когда вы возвращаетесь к странице редактирования – вы будет видеть три дополнительных поля для вариантов ответа.
В конце списка вариантов ответа – вы увидите ссылку на добавление ещё одного варианта – Add another Choice. Если кликнуть на него – будет добавлено ещё оно поле. Если вы хотите удалить его – можно кликнуть на крестик справа вверху поля, но вы не сможете удалить первые три поля.
Вот как это выглядит:
Однако – есть небольшая проблема. Список вариантов ответов занимает много места на экране. Поэтмоу – Django предоставляет табличный способ отображения связанных объектов. Вам надо только изменить описание ChoiceInline
:
class ChoiceInline(admin.TabularInline): model = Choice extra = 3
Используя метод TabularInline
вместо StackedInline
– связанные объекты будут отображаться более компактно:
Настройка списка редактирования
Теперь, когда страница управления Question выглядит так, как мы хотим – давайте немного изменим страницу изменений – то есть ту страницу, где отображаются все наши вопросы.
Вот как она выглядит в настоящий момент:
По умолчанию – Django отображает str()
каждого объекта. Но иногда может потребоваться отобразить отдельные поля. Что бы сделать это – используйте опцию админпанели list_display
, которая является кортежем, содержащим поля для отображения. Отредактируйте файл polls/admin.py
:
... class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] list_display = ('question_text', 'pub_date') ...
Давайте так же включим сюда дополнительное поле was_published_recently
, которое мы создали в предыдущей части:
... 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): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') 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_display
для отображения страницы изменений Question:
... class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] list_display = ('question_text', 'pub_date', 'was_published_recently') list_filter = ['pub_date'] ...
Это добавит сайдбар Filter, который позволит выполнять сортировку по полю pub_date
:
Тип фильтра будет зависеть от типа поля, которое вы добавили в фильтр. Так как pub_date
– это объект DateTimeField
– Django знает, что подходящие фильтры тут – это “Any date“, “Today“, “Past 7 days“, “This month” и “This year“.
Давайте так же добавим возможно поиска по вопросам:
... class QuestionAdmin(admin.ModelAdmin): #... search_fields = ['question_text'] ...
Этим мы добавляем поле для поиска вверху страницу изменений:
Когда кто-то введёт текст для поиска – Django выполнит его поиск по полю question_text
. Вы можете использовать любое количество полей, однако – так как тут используется SQL оператор LIKE
– ограниченное количество полей для поиска сделает поиск более простым.
Также стоит обратить ваше внимание на то, что на странице изменений можно настроить нумерацию страниц. По умолчанию – будут отображаться 100 записей на одну страницу. С помощью change list pagination
, search boxes
, filters
, date-hierarchies
и column-header-ordering
можно настроить вид админпанели так, как вы этого хотите.
Настройка внешнего вида панели управления
Если честно, надпись “Django administration” вверху панели управления выглядит не к месту.
Но – это очень просто изменить с помощью системы шаблонов Django. Панель управления Django управляется самой Django, а её внешний вид – это родная система шаблонов Django.
Настройка шаблонов проекта
Создайте каталог templates
в каталоге вашего проекта (том, который содержит файл manage.py
). Шаблоны могут располагаться где угодно в файловой системе, лишь бы 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 на наличие файлов шаблонов.
Теперь – в каталоге templates
создайте каталог admin
, и скопируйте файл admin/base_site.html
из каталога шаблонов Django – django/contrib/admin/templates
в этот каталог (/usr/local/lib/python2.7/site-packages/Django-1.8.1-py2.7.egg/django/contrib/admin/templates/admin/
, если вы устанавливали Django на CentOS по статье CentOS: обновление Python до 2.7 и установка Django 1.8):
$ mkdir templates/admin $ cp /usr/local/lib/python2.7/site-packages/Django-1.8.1-py2.7.egg/django/contrib/admin/templates/admin/base_site.html templates/admin/
Где исходные файлы Djnago?
Если у вас возникли сложности с поиском исходных файлов 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. Когда Django рендерит файл admin/base_site.html
– этот язык шаблонов будет превращён в обычный HTML. Мы рассмотрим систему шаблонов далее (либо – вы можете с ней познакомиться на странице Django Book: основы системы шаблонов).
Заметьте, что любые дефолтные шаблоны админпанели Django могут быть перезаписаны. Что бы перезаписать шаблон – просто повторите те же шаги, которые вы сделали с файлом base_site.html
– скопируйте его в ваш каталог, и отредактируйте.
Настройка шаблонов приложения
Внимательные читатели могут спросить – “Но если DIRS
пуста по умолчанию – как Django находит свои шаблоны изначально?“. Ответ заключается в параметре APP_DIRS
– так как он установлен в True
, Django автоматически ищет каталог templates
внутри каждого приложения, а django.contrib.admin
сам по себе является простым приложением Django.
Наше приложение голосования достаточно простое, и не требует особых настроек админпанели. Однако, если вам это потребуется – то лучше редактировать шаблон приложения, а не проекта.
Настройка главной страницы админпанели
Вы так же, возможно, захотите изменить внешний вид главной страницы админпанели.
По умолчанию – тут отображаются все приложения из списка INSTALLED_APPS
, которые были зарегистрированы приложением admin
, в алфавитном порядке.
Для изменения вида главной страницы админпанели используется файл admin/index.html
(проделайте те же действия с ним, что и с файлом admin/base_site.html
– скопируйте его в свой каталог templates
). Откройте файл для редактирования – и вы увидите переменную, которая называется app_list
. Именно она содержит все установленные приложения Django. Вместо её использования – вы можете вручную вписать ссылки на объекты в панели управления, которые вы хотели бы отобразить.
Примечание: русификация панели управления описана в статье Django book: использование панели управления.