Администрирование Django
Чтобы добавлять, редактировать и удалять записи, для которых мы только что создали модель, мы используем панель управления администратора Django.
Давай откроем файл blog/admin.py и заменим его содержимое на:
from django.contrib import admin from .models import Post admin.site.register(Post)
Как ты можешь заметить, мы импортировали (включили) модель Post, которую определили в предыдущей главе. Чтобы наша модель стала доступна на странице администрирования, нам нужно зарегистрировать её при помощи admin.site.register(Post) .
Хорошо, теперь нам нужно взглянуть на модель Post. Не забудь запустить веб-сервер командой python manage.py runserver . Перейди в браузер и набери адрес http://127.0.0.1:8000/admin/. Ты увидишь страницу авторизации:
Чтобы залогиниться, тебе сначала нужно создать суперпользователя (англ. superuser) — пользователя, который имеет полный доступ к управлению сайтом. Вернись к командной строке, набери python manage.py createsuperuser , и нажми Enter.
Не забудь: чтобы выполнять команды во время работы сервера, открой новое окно терминала и активируй в нём виртуальное окружение. Мы описывали ввод новых команд в разделе Запуск веб-сервера главы Твой первый проект на Django!.
При появлении запроса введи имя пользователя (строчными буквами, без пробелов), адрес электронной почты и пароль. Не беспокойся, если пароль не появляется на экране по мере ввода, так и задумано. Просто напечатай его и нажми Enter , чтобы продолжить. Результат должен выглядеть следующим образом (имя пользователя и почта, соответственно, будут твоими):
(myvenv) ~/djangogirls$ python manage.py createsuperuser Username: admin Email address: admin@admin.com Password: Password (again): Superuser created successfully.
Вернись в браузер и войди в систему при помощи имени пользователя и пароля, которые ты только что выбрала. Ты должна попасть в панель управления Django.
Перейди к разделу Posts и немного поэкспериментируй с ним. Добавь пять или шесть постов. Не беспокойся о содержании — можешь просто скопировать и вставить текст из этого учебника, чтобы сэкономить время 🙂
Убедись, что выбрала для двух или трёх записей (но не больше) дату публикации. Это пригодится позднее.
Если ты хочешь узнать больше об администрировании Django, то ознакомься с этим разделом официальной документации: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/.
Сейчас, вероятно, подходящий момент, чтобы порадовать себя кружечкой кофе (или чая), а также съесть чего-нибудь для восполнения энергии. Ты только что создала свою первую модель Django и заслужила перерыв!
results matching » «
No results matching » «
Тонкая настройка админ панели
На этом занятии мы сделаем некоторые изменения в админ-панели, настроим ее под свой разрабатываемый сайт. Если перейти в документацию по Django, то на официальной странице:
есть раздел «Admin» и ссылка «Admin site», где подробно объясняются различные нюансы настройки админ-панели. Это огромная тема, поэтому, мы коснемся лишь некоторых базовых вещей.
Меняем стили оформления
- admin/index.html D:\\Python\\django\\djsite\\venv\\lib\\site-packages\\django\\contrib\\admin\\templates\\admin\\index.html
- admin/base_site.html D:\\Python\\django\\djsite\\venv\\lib\\site-packages\\django\\contrib\\admin\\templates\\admin\\base_site.html
- admin/base.html D:\\Python\\django\\djsite\\venv\\lib\\site-packages\\django\\contrib\\admin\\templates\\admin\\base.html
- admin/app_list.html D:\\Python\\django\\djsite\\venv\\lib\\site-packages\\django\\contrib\\admin\\templates\\admin\\app_list.html
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], . }, ]
- block title – отвечает за отображение заголовка во вкладке;
- block branding – за отображение ссылки «Администрирование Django» в верхней панели;
- block nav-global – глобальный блок навигации.
{% block extrastyle %} link rel="stylesheet" href=""> {% endblock %}
Соответственно, выше загрузим тег static:
{% load static %}
и сформируем файл admin.css в нашем приложении в каталоге static/css:
#header background: #5e3a00; }
Почему мы прописали именно такой селектор для изменения цвета верхней панели? Очень просто. Если перейти в браузер и проинспектировать этот элемент, то увидим тег div с Значит, для назначения свойств, можно использовать этот идентификатор. По аналогии можно переобозначать стили для всех других элементов админ-панели. Например, такой же стиль пропишем и для заголовков блоков:
#header, .module caption background: #5e3a00; }
Я думаю, общий принцип понятен. Этим способом можно переопределить все стили и настроить вид админки под дизайн, цветовую схему вашего сайта. Если же вам нужно изменить сам заголовок «Администрирование Django», то это лучше делать через модуль admin (файл women/admin.py), в котором, следует определить два таких атрибута:
admin.site.site_title = 'Админ-панель сайта о женщинах' admin.site.site_header = 'Админ-панель сайта о женщинах'
Полный список подобных атрибутов можно посмотреть на странице документации: https://docs.djangoproject.com/en/3.1/ref/contrib/admin/
Добавляем отображение изображений для постов в списке
Следующим шагом добавим отображение миниатюр изображений, связанных с нашими постами, непосредственно в списке. Сейчас у нас происходит отображение пути к изображению в колонке «Фото». Мы же хотим показывать непосредственно изображение, а не путь. Как это сделать? Для этого в классе WomenAdmin (файл women/admin.py) следует прописать метод, который бы возвращал HTML-код. И этот HTML-фрагмент, затем, подставим вместо путей. Имя метода мы придумываем сами, например, так:
def get_html_photo(self, object): return mark_safe(f"")
Этот метод будет принимать второй параметр object – ссылку на текущую запись (на текущий пост) и, затем, возвращаем фрагмент HTML, но помеченный фильтром safe, чтобы теги воспринимались как теги и не экранировались, то есть, не заменялись бы спецсимволами. Именно для этого и используется функция mark_safe(). Все, если теперь вместо поля photo (в списке list_display) указать метод get_html_photo:
list_display = ('id', 'title', 'time_create', 'get_html_photo', 'is_published')
должны увидеть вместо маршрутов картинки, связанные с постами. Однако, у нас отображается ошибка с исключением ValueError, так как не все посты имеют изображения. Поэтому в методе get_html_photo следует прописать проверку:
def get_html_photo(self, object): if object.photo: return mark_safe(f"")
Причем, по else можно ничего не возвращать (будет формироваться значение None), тогда Django автоматически поставит дефис там, где фотография отсутствует. Если же прописать иначе:
def get_html_photo(self, object): if object.photo: return mark_safe(f"") else: return "Нет фото"
То вместо дефиса увидим нашу строку «Нет фото». Наконец, чтобы поменять название столбца (вместо «GET HTML PHOTO»), нужно у объекта-метода get_html_photo определить специальный атрибут:
get_html_photo.short_description = "Миниатюра"
Этот пример с выводом фотографии показывает, как можно заменять стандартный вывод полей списка на свой собственный, определяя дополнительные специальные методы и указывая их в списке list_display. То есть, следуя этому принципу, мы можем формировать самую разную информацию для отображения в списках. Наконец, мы можем сделать вывод фотографии и непосредственно на странице редактирования поста. Для этого, опять же в классе WomenAdmin (файл women/admin.py) пропишем еще один атрибут:
fields = ('title', 'slug', 'cat', 'content', 'photo', 'is_published')
Этот атрибут содержит порядок и список редактируемых полей, которые следует отображать в форме редактирования. Если же дополнительно нужно показывать не редактируемые поля, то дополнительно нужно прописать атрибут:
readonly_fields = ('time_create', 'time_update')
И только после этого, их можно добавить в коллекцию fields:
fields = ('title', 'slug', 'cat', 'content', 'photo', 'is_published', 'time_create', 'time_update')
Отлично, это мы сделали, но как отобразить миниатюру? Для этого достаточно указать ссылку на наш метод get_html_photo() в этих атрибутах:
fields = ('title', 'slug', 'cat', 'content', 'photo', 'get_html_photo', 'is_published', 'time_create', 'time_update') readonly_fields = ('time_create', 'time_update', 'get_html_photo')
Все, теперь мы видим изображение загруженной фотографии в форме редактирования. Чтобы узнать о других возможностях настройки формы редактирования, на странице документации можно посмотреть список атрибутов для класса ModelAdmin. В частности, установка вот такого атрибута:
save_on_top = True
Django Admin с миллионами записей — 11 практик оптимизаций для начинающих
Django — самый популярный Python web-framework. За больше чем 10 лет оброс огромным слоем возможностей. Среди них можно выделить — Django Admin — это готовый CRUDL интерфейс с поиском, фильтрами и хитрыми настройками.
Каждый раз стартуя проект на Django, удивляюсь насколько круто иметь админку — web интерфейс просмотра данных. Да еще и бесплатно.
Каждый раз поддерживая проект на Django, удивляюсь, как же сложно поддерживать админку в рабочем состоянии.
В этой статье я постараюсь привести 11 практик, которые позволят избегать тормозов админки максимально долго.
Дисклеймер: эта статья была написана в марте 2017 года, на тот момент она была слаба для хабра, но прошло 4 года и теперь может найти своего начинающего django разработчика. А в Django изменилось мало.
Какие-то из практик оптимизации админки элементарные — добавить одну строчку, какие-то требуют перегрузить ряд методов, а оставшиеся — это что стоит поменять в разработке.
Практика 1 — raw_id_fields
В любом мало-мальском проекте мы встретим модели с ForeingKey/Many2Many полями, которые очень интересно отображаются в админке. Например, ForeingKey поля отображаются как select, в котором перечислены все элементы связей:
Стандартный select совсем не удобен при количество связей больше 20 — нет поиска.
Изначально подход с select не практичен, и поиска нет, да и медленный он. Как это бывает — начало проекта, 10 связей, 100, 1000 иии вот страница редактирования элемента начинает грузиться не доли секунд, а уже секунды. Связей 10к, 100к и страница перестает грузиться и падает с Timeout Error.
Чтобы избежать этого и добавить поиск достаточно воспользоваться переменной raw_id_fields
Указав название поля в переменной raw_id_fields — мы перегружаем виджет отображения, который не делает лишних запросов в БД:
@admin.register(ModelA) class ModelAAdmin(admin.ModelAdmin): list_display = [ 'value', ] search_fields = ['value'] @admin.register(ModelB) class ModelBAdmin(admin.ModelAdmin): list_display = [ 'name', 'data', ] raw_id_fields = ['data', ]
В дополнение — используйте django-ajax-selects или django-autocomplete-light
Практика 2 — выгружайте все необходимое одним запросом
В документации к QuerySet можно найти два метода — select_related и prefetch_related. Эти методы полезны, когда у вас есть ForeinKey/Many2Many поля и по ним что-то отображаете.
select_related в один запрос выгружает элементы ForeinKey/Many2Many (делает JOIN таблиц)
prefetch_related делает тоже самое, но не JOIN’ом, а дополнительными SELECT запросами.
Вы можете использовать эти конструкции и в админке:
class ModelBAdmin(admin.ModelAdmin): list_display = [ 'name', 'data', ] list_select_related = ['data', ]
class ModelBAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super(ModelBAdmin, self).queryset(request) return qs.prefetch_related('data')
В первом и втором варианте мы подсказали админке, что нам потребуются дополнительные данные и Django ORM чуть-чуть сэкономит время.
А на самом деле, лучше избегать JOIN запросов — они тяжелые для БД и это заметно в работе админки.
Практика 3
Отходя от ForeingKey/Many2Many связей поговорим про количество элементов в таблице.
Помните, что РСУБД не гарантирует порядок кортежей/строк? Так вот, всегда есть соблазн делать какую-то сортировку, например по времени или по ID. Если у вас мало элементов и сервер мощный, то он мгновенно делает ORDER BY по вашему полю, однако, когда записей становится много, то простой SQL запрос
SELECT "app_modelb"."id", "app_modelb"."name", "app_modelb"."data_id", "app_modela"."id", "app_modela"."value" FROM "app_modelb" INNER JOIN "app_modela" ON ("app_modelb"."data_id" = "app_modela"."id") ORDER BY "app_modelb"."name" ASC, "app_modelb"."id" DESC
Может занимать уже секунды или даже минуты. И здесь не поможет никакой хитрый индекс.
В Django Admin есть параметр ordering. Чтобы ваша база не пухла от странных запросов, стоит убедится что нигде не указываете этот порядок — обычно его устанавливают в самом AdminModel и в Meta у моделей.
@admin.register(ModelB) class ModelBAdmin(admin.ModelAdmin): list_display = [ 'name', 'data', ] ordering = []
Если вам все же потребуется сортировка — вы можете сначала выбрать нужный набор фильтров, а потом по результатам выборки сделать сортировку.
Практика 4
Переходя от основных настроек админки перейдем к второстепенным.
Вам точно надо знать количество элементов в таблице?
В стандартной админке есть интересная штука — количество элементов в таблице.
Чтобы показать это число, Django генерирует запрос вида
SELECT COUNT(*) AS "__count" FROM "app_modela"
Когда у вас таблица маленькая, 1к, 10к, 100к — Count(*) работает быстро, а когда вы переходите за миллион и десятки миллионов, то безобидная операция подсчета элементов может занимать больше 30 секунд и в конечном итоге приводить к Time out error
Для РСУБД PostgreSQL и MySQL давно есть способы приблизительно подсчитать количество элементов в таблице не делая тяжелых запросов:
# mysql SHOW TABLE STATUS LIKE table_name # postgresql SELECT reltuples::bigint FROM pg_class WHERE relname = table_name
Оба запроса получают информацию о количестве элементов в table_name из системной таблицы. Это значительно быстрее, чем Count запрос.
Используя эту идею, можно переопределить ChangeList админ модели. К сожалению, там не две строчки кода, поэтому скину ссылку на github, где показан пример — https://github.com/WarmongeR1/django-admin-article/blob/master/app/admin_opt.py#L58
В том же модуле есть код перегрузки пагинатора для Django Admin.
Практика 5 — 25 раз по мало < один раз по много
Рассмотрим типичный сценарий — есть таблица юзеров и данные пользователя, например, покупки. Таблицу юзеров спокойно выводим в админку:
@admin.register(User) class UserAdmin(admin.ModelAdmin): list_display = [ 'email', 'field1' 'field2' ] search_fields = ['email', ]
Все работает отлично, в БД отправляет простой SELECT. Теперь делаем вывод второй таблицы
@admin.register(UserData) class DataAdmin(admin.ModelAdmin): list_display = [ 'user', 'field3' 'field4' ]
Смотрим в django-debug-toolbar и видим интересный по неоптимальности запрос:
SELECT ••• FROM "table_userdata" INNER JOIN "table_user" ON ("table_data"."user_id" = "table_user"."id") ORDER BY "accounts_weightdata"."id" DESC LIMIT 25
INNER JOIN с таблицей пользователей. Для маленьких таблиц это не страшно, все летает, но чем больше таблицы, тем дороже этот JOIN.
Чтобы решить эту проблему можно зайти с другой стороны и заменить долгий запрос на несколько недолгих. А именно — сделать обычный SELECT по таблице с данными, а затем отдельными запросами сходить за информацией о пользователей. (Кстати, эти SELECT’ы можно еще и в кэш положить):
@admin.register(UserData) class DataAdmin(admin.ModelAdmin): list_display = [ 'user_email', 'field3' 'field4' ] raw_id_fields = ['user'] def user_email(self, instance): CACHE_KEY = 'admin:<>:instance:<>'.format( 'user', instance.user_id ) result = cache.get(CACHE_KEY) if not result: result = instance.user.email cache.set(CACHE_KEY, result) return result
Практика 6 — перегрузить поиск
Админка без поиска — время на ветер.
Добавить поиск по полю — элементарно
search_fields = ['field', ]
И как это бывает — есть модель с данными пользователя и мы добавляем поиск по email/имени:
@admin.register(UserData) class UserDataModel(admin.ModelAdmin): list_display = ['value', ] search_fields = ['user__email', ]
И начиаем пользоваться. Когда таблица пользователей и таблица с данными разростается, замечаем что любая попытка найти что-то приводит к Time out error.
Тут то и берем debug toolbar и смотрим нам запрос поиска:
SELECT "user_data"."id", "user_data"."user_id", "user_data"."field1", "user_data"."field2" FROM "user_data" INNER JOIN "user_table" ON ("user_data"."user_id" = "user_table"."id") WHERE UPPER("user_table"."email"::text) LIKE UPPER('%email%') ORDER BY "accounts_sleepdata"."id" DESC
Обратите внимание на JOIN. Наверное вы уже запомнили, что JOIN это дорогая операция и их надо избегать. Почесав тыковку можно придти мысль — а что если как-то избежать использование таблицы пользователей или хотя бы убрать JOIN.
И у меня есть идея, как это сделать. А что если если пользователь ввел email в поисковую строку, то преобразовать его в id и уже по нему сделать поиск.
Изучая документацию Django, можно найти метод get_search_results, он дополняет QuerySet после фильтров поиском по полям.
Вот его и перегружаем
def get_user_by_email(email): try: return User.objects.get(email__iexact=email) except User.DoestNotExist: return None class UserEmailSearchAdmin(admin.ModelAdmin): def get_search_results(self, request, queryset, search_term): user = get_user_by_email(search_term) if user is not None: queryset = queryset.filter(user_id=user.id) use_distinct = False else: queryset, use_distinct = super().get_search_results(request, queryset, search_term) return queryset, use_distinct @admin.register(UserData) class UserDataModel(UserEmailSearchAdmin): list_display = ['value', ] search_fields = ['user__email', ]
Вводим полноценный email — получаем оптимальный запрос.
SELECT "user_data"."id", "user_data"."user_id", "user_data"."field1", "user_data"."field2" FROM "user_data" INNER JOIN "user_table" ON ("user_data"."user_id" = "user_table"."id") WHERE "accounts_sleepdata"."user_id" = ORDER BY "accounts_sleepdata"."id" DESC
Если же вводим часть email или другую строку — то делается страшный JOIN
Практика 7 — продумай заранее индексы
При активной разработке постоянно есть недостаток времени и каждый раз хочется где-то схалявить. Так вот, технический долг, который находится на уровне моделей — очень дорогой.
Разрабатывая фичу, продумайте несколько use case, и подумайте, как будете визуализировать результаты работы фичи, что вам понадобиться, что нет.
Лишний день при разработке структуры БД поможет сэкономить недели в будущем.
Индекс по текстовому полю ускорит поиск, вот только база (индекс) начнет расти молниеносно.
Практика 8 — не используй сложные фильтры в админке
У Django есть удобный инструмент фильтров в админке. Он позволяет получить нужные выборки. Для выборок аля «Пользователи со статусом A» подходит хорошо. Но если вы хотите получить сложную выборку «Пользователи со статусом А, возрастом Б и не в группе С», то легко получить неоптимальный запрос вида:
SELECT * FROM table WHERE id not in [1, 2, 3, . 100000. ]
Научить Django ORM оптимизировать сложные запросы тяжело и не имеет смысла. Значительно проще писать голые SQL запросы.
Этот инструмент предоставляет веб-интерфейс работы с SQL. Он не дотягивает до pg_admin и аналогов и умеет совсем мало — выполнять запросы, сохранять их для переиспользования и сохранять выборки в различные форматы файлов.
Чтобы внедрить — достаточно установить, определить кому будет доступ и написать готовые SQL запросы, которые ваша команда будет использовать.
Практика 9 — упрости жизнь базе
Когда вы заходите на страницу модели в админке, вам точно надо select по всему? Может лучше вообще пустую страницу показать или за последний день?
Набор элементов для отображения определяется методом get_queryset и так его можно перегрузить:
@admin.register(ModelA) class ModelAAdmin(admin.ModelAdmin): def get_queryset(self, request): if len(request.GET) == 0: return ModelA.objects.none() else: return super().get_queryset(request)
В этом примере я перегрузил QuerySet по умолчанию — если открыть страницу таблицы, то увидим пустую страницу (без элементов), однако, если начнем искать — то результаты будут видны.
Практика 10 — не знаешь зачем тебе данные → не собирай их → не показывай их.
Всегда есть соблазн, начать собирать от пользователей какую-то мелоч, которая в далеком светлом будущем может помочь улучшить продукт. Так вот — если у вас нет мыслей как использовать эти данные — они вам не нужны сейчас.
Любая модель, которую вы создали в порыве за 2 минуты, будете в будущем выпиливать несколько месяцев.
Практика 11 — группируй модели в группы по смыслу.
Развивая продукт как монолит, мы получаем огромное количество моделей, где даже найти нужную модель тяжело. Чтобы упростить поиск — группируйте модели с помощью батарейки django-admin-tools .
Батарейка умеет делать разные дашбоарды, на которых перечень и способ отображения моделей может быть разным. Такое разделение помогает, если данные используют разные отделы компании.
Управление группами идет из кода — вот пример такого конфига
Выводы
Сколько бы Django Admin не ругали или восхваляли — это интересный инструмент со множеством подводных камней. Чтобы выжать максимум пользы придется покапаться в настройках, а иногда и перегрузить методы, шаблоны.
Что касается производительности — таблица со 100 миллионами записей прекрасно открывается в Django Admin.
P.S. Разумеется, если нужны сложные выборки и таблицы, то инструменты типа Metabase или Redash, админка не заменит.
Руководство Django часть 4: административная панель Django
Теперь, когда модели для сайта местной библиотеки созданы, добавим некоторые «настоящие» данные о книгах, используя административную панель Django Admin. Для начала мы покажем, как зарегистрировать в ней модели, потом как войти и создать какие-нибудь данные. В конце статьи мы покажем некоторые способы дальнейшего улучшения вида админ-панели.
Предусловия: | Сначала завершите: Руководство часть 3: использование моделей. |
---|---|
Цель: | Уяснить преимущества и ограничения админ-панели Django, научиться использовать её для создания записей для наших моделей. |
Обзор
Приложение Django admin может использовать ваши модели для автоматического создания части сайта, предназначенной для создания, просмотра, обновления и удаления записей. Это может сэкономить вам много времени в процессе разработки, упрощая тестирование ваших моделей на предмет правильности данных. Оно также может быть полезным для управления данными на стадии публикации, в зависимости от типа веб-сайта. Проект Django рекомендует это приложение только для управления внутренними данными (т.е.для использования администраторами, либо людьми внутри вашей организации), так как модельно-ориентированный подход не обязательно является наилучшим интерфейсом для всех пользователей и раскрывает много лишних подробностей о моделях.
Все необходимые настройки, которые необходимо включить в admin приложение вашего веб-сайта, были сделаны автоматически, когда вы создали каркас проекта ( информацию о необходимых актуальных зависимостях смотрите здесь — Django docs) . В результате все, что необходимо сделать для того, чтобы добавить модели в приложение admin, это зарегистрировать их. В конце этой статьи мы представим краткую демонстрацию того, каким образом можно дополнительно настроить админ-панель для лучшего отображения данные наших моделей.
После регистрации моделей мы покажем как создать нового суперпользователя , войти на сайт от его имени и создать книги, авторов, экземпляры книг и жанры. Это будет полезным для тестирования представлений и шаблонов, которые мы начнём создавать в следующей части руководства.
Регистрация моделей
Вначале откройте файл admin.py в папке приложения (/locallibrary/catalog/admin.py). Пока он выглядит так (заметьте, что он уже содержит импорт django.contrib.admin) :
from django.contrib import admin # Register your models here.
Зарегистрируйте модели путём вставки следующего текста в нижнюю часть этого файла. Этот код просто импортирует модели и затем вызывает admin.site.register для регистрации каждой из них.
from .models import Author, Genre, Book, BookInstance admin.site.register(Book) admin.site.register(Author) admin.site.register(Genre) admin.site.register(BookInstance)
Примечание: Если вы приняли участие в создании модели для представления естественного языка книги (см. обучающую статью о моделях), импортируйте и зарегистрируйте её тоже!
Это самый простой способ регистрации модели или моделей. Админ-панель имеет множество настроек. Мы рассмотрим другие способы регистрации ваших моделей ниже.
Создание суперпользователя
Для того, чтобы войти в админ-панель, нам необходимо иметь учётную запись пользователя со статусом Staff (сотрудники). Для просмотра и создания записей, пользователю также понадобится разрешение для управления всеми нашими объектами. Вы можете создать учётную запись «superuser», которая даёт полный доступ к сайту и все необходимые разрешения, используя manage.py.
Для создания суперпользователя вызовите следующую команду из той же папки, где расположен manage.py. Вас попросят ввести имя пользователя, адрес электронной почты и надёжный пароль.
bash
Вход в админ-панель и её использование
Для входа в админ-панель откройте ссылку /admin (например http://127.0.0.1:8000/admin) и введите логин и пароль вашего нового суперпользователя (вас перенаправят на login-страницу и потом обратно на /admin после ввода всех деталей).
В этой части сайта отображаются все наши модели, сгруппированные по установленному приложению. Вы можете кликнуть на названии модели, чтобы получить список всех связанных записей, далее можете кликнуть на этих записях, для их редактирования . Также можно непосредственно кликнуть на ссылку Add, расположенную рядом с каждой моделью, чтобы начать создание записи этого типа.
Кликните на ссылке Add справа от Books, чтобы создать новую книгу (появится диалоговое окно как на картинке внизу). Заметьте, что заголовок каждого поля - это тип используемого виджета, и
help_text
(если есть) совпадает со значением, которое вы указали в модели.Введите значение для полей. Вы можете создавать новых авторов или жанры, нажимая на значок "+ ", расположенный рядом с соответствующим полем (или выберите существующее значение из списков, если вы уже создали их). Когда вы закончили, нажмите на SAVE,Save and add another, или Save and continue editing, чтобы сохранить записи.
Примечание: А сейчас, хотелось бы, чтобы вы добавили несколько книг, авторов и жанров (например, Фэнтези) в ваше приложение. Удостоверьтесь, что каждый автор и жанр включает пару различных книг (позже, когда мы реализуем представления "list" и "detail", это сделает их более интересными).
После того, когда книги добавлены, для перехода на главную страницу админ-панели кликните на ссылке Home в верхней части страницы. Потом кликните на ссылке Books для отображения текущего списка книг (или на одной из других ссылок, чтобы увидеть список соответствующей модели). После добавления нескольких книг список может выглядеть наподобие скриншота ниже. Отображается название каждой из книг. Его возвращает метод
__str__()
в модели Book, созданной в предыдущей статье.
Для удаления книги из этого списка выберите чекбокс рядом с ней и действие delete. из выпадающего списка Action, а затем нажмите кнопку Go. Также можно добавить новую книгу, нажав на кнопку ADD BOOK.
Вы можете редактировать книгу, кликнув по ссылке с её названием. Страница редактирования книги, приведённая ниже, практически идентична странице добавления новой книги. Основные отличия - это заголовок страницы (Change book) и наличие кнопок Delete, HISTORY и VIEW ON SITE. Последняя присутствует, так как мы определили метод
get_absolute_url()
в нашей модели.
Теперь перейдите назад на страницу Home (используя ссылку Home в навигационной цепочке вверху страницы) и просмотрите списки Author и Genre. В них уже должно быть несколько элементов, созданных при добавлении новых книг. Если хотите, добавьте ещё.
Однако у вас не будет ни одного экземпляра книги, потому что они не создаются из модели
Book
(хотя можно создать книгу из моделиBookInstance
— такова природа поляForeignKey
). Для отображения страницы Add book instance (см. рисунок ниже) вернитесь на страницу Home и нажмите кнопку Add. Обратите внимание на длинный уникальный Id для идентификации конкретного экземпляра книги в библиотеке.
Создайте несколько экземпляров для каждой из ваших книг. Установите статус Available (доступен) для некоторых экземпляров и On loan (выдан) для остальных. Если статус экземпляра notAvailable (недоступен), то также установите дату возврата (Due back).
Вот и все! Вы изучили как запустить и использовать админ-панель. Также были созданы записи для
Book
,BookInstance
,Genre
иAuthor
, которые можно будет использовать после создания наших собственных представлений и шаблонов."Продвинутая" конфигурация
Django выполняет неплохую работу по созданию базовой админ-панели используя информацию из зарегистрированных моделей:
- каждая модель имеет список записей, каждая из которых идентифицируется строкой, создаваемой методом
__str__()
модели, и связана с представлением для её редактирования. По умолчанию, в верхней части этого представления находится меню действий, которое может быть использовано для удаления нескольких записей за раз- Формы для редактирования и добавления записей содержат все поля модели, которые расположены вертикально в порядке их объявления в модели.
Можно настроить интерфейс пользователя для упрощения его использования. Некоторые доступные настройки:
- List views:
- добавление дополнительных отображаемых полей или информации для каждой записи.
- добавление фильтров для отбора записей по разным критериям (например, статус выдачи книги).
- добавление дополнительных вариантов выбора в меню действий и места расположения этого меню на форме.
- Detail views
- выбор отображаемых полей, их порядка, группирования и т.д.
- добавление связанных полей к записи (например, возможности добавления и редактирования записей книг при создании записи автора).
В этом разделе рассмотрим некоторые изменения для совершенствования интерфейса пользователя нашей местной библиотеки, а именно: добавление дополнительной информации в списки моделей
Book
иAuthor
, а также улучшение расположения элементов соответствующих представлений редактирования. Пользовательский интерфейс моделейLanguage
andGenre
изменять не будем, так как это не даст заметного улучшения, поскольку он содержит только по одному полю!Полное руководство по всем возможным вариантам настройки админ-панели можно найти в The Django Admin site (документация Django).
Регистрация класса ModelAdmin
Для изменения отображения модели в пользовательском интерфейсе админ-панели, необходимо определить класс ModelAdmin (он описывает расположение элементов интерфейса, где Model - наименование модели) и зарегистрировать его для использования с этой моделью.
Давайте начнём с модели Author. Откройте файл admin.py в каталоге приложения (/locallibrary/catalog/admin.py). Закомментируйте исходную регистрацию (используя префикс #) этой модели:
js
.site.register(Author)Теперь добавьте новый класс AuthorAdmin и зарегистрируйте его как показано ниже:
# Define the admin class class AuthorAdmin(admin.ModelAdmin): pass # Register the admin class with the associated model admin.site.register(Author, AuthorAdmin)Сейчас мы добавим классы ModelAdmin для моделей Book , и BookInstance . Нам снова нужно закомментировать исходную регистрацию:
.site.register(Book) #admin.site.register(BookInstance)