Admin django-cms — admin django-cms


Содержание

Начинаем работу с Django — подключение админки

На предыдущем шаге нами заданы структуры данных для хранения списка вопросов и вариантов ответов для них.

Пока мы еще ничего не сделали для того, чтобы иметь возможность работать с данными через сайт. Но Django предосставляет нам мощную систему администрирования для управления данными нашего сайта прямо из коробки. Админка Django не предназначена для обычных посетителей сайта. Скорее это средство, упрощающее для администратора работу с данными. Django автоматически создает интерфейс для управления нашими данными на базе созданных нами моделей также, как создает соотвествующие им таблицы в базе данных.

Включение админки Django

Чтобы начать использовать админку сайта, предоставляемую Django, нужно предварительно выполенить несколько действий.

Во-первых, в файле настроек проекта settings.py нужно раскоментировать строку django.contrib.admin

Теперь нам снова нужно выполнить команду

Django создаст в базе данных таблицы, которые необходимы для работы админской части сайта.

Теперь нужно отредактировать файл mysite/urls.py, чтобы сообщить Dajngo, какой код нужно вызвать, когда мы обратимся через браузер к админке.

Для этого раскоментируем нужные строки. Теперь файл mysite/urls.py должен выглядеть так:

Строки, которые нужно раскоментировать, подсвечены жирным шрифтом.

Для запуска нашего сайта выполним команду

В консоли вы должны увидеть

Это означает, что все в порядке, и мы можем начинать работу с сайтом. Но вместо http://127.0.0.1:8000/ откроем http://127.0.0.1:8000/admin/

Вы должны увидеть приглашение ввести логин и пароль для входа в админку Django

Входим в админку, используя указанные на первом шаге логин и пароль супер-пользователя.

Создание суперпользователя админки Django

Если по какой-то причине вы не создали суперпользователя раньше, то вы можете это сделать, выполнив консоли команду

Зайдя в админку, вы должны увидеть подобную картину:

Вы уже можете добавить пользователей для управления сайтом и группы, определяющие их права, а также изменить настройки сайта. Однако пока еще нельзя добавить или редактировать созданные нами модели Вопросов и Ответов.

Отображение объектов в админке Django — подключаем наши модели

Чтобы получить доступ к изменению объектов через админ. часть сайта, нужно зарегистрировать их в приложении admin.

Создайте новый файл в каталоге polls с названием admin.py. В файл вставьте следующий текст:

Теперь перезапустите сервер и обновите или зайдите заново в админку.

Порядок! Теперь нам доступно создание и редактирование новых вопросов через пункт Polls.

Django автоматически формирует веб-форму на базе модели, которая позволяет ввести все нужные данные. При этом еще не будет введено какое-то из полей, отмеченных как обязательное, форма вернет нас к редактированию подсветив нужные поля для ввода:

После заполнения всех полей и сохранения объекта, информация о нем сохраняется в базе данных.

Новый объект появился в списке, однако выглядит не очень информативно:

Дело в том, что для вывода информации об объекте Django использует метод __unicode__(). В созданном нами классе Poll нет такого метода. Добавим его.

Добавление названия объектам

Для вывода информативного названия объекта, добавим метод __unicode__() к классам Poll и Choice.

Отредактируем models.py, добавив выделенный жирным текст:

Теперь после обновления списка объектов Poll в админке используется текст, который мы ввели в качестве вопроса:

Добавление связанных объектов

Чтобы можно было добавить новые варианты ответов через админку, достаточно в файле admin.py добавить:

Теперь “Choices” появилась в Django admin. При добавлении нового варианта ответа нужно будет выбрать соответствующий вопрос:

Однако это не очень удобно. В списке выбора вопроса будут все вопросы, которые были сохранены в базе. Кроме того, логично вводить варианты ответов при добавлении вопроса.

Давайте сделаем это.

В файле admin.py уберем register() для класса Choice и отредактируем регистрацию класса Poll. Измените текст на приведенный ниже.

Теперь объекты Choice могут быть добавлены сразу при добавлении вопроса, при этом Django предложит заполнить сразу 3 варианта, а при необходимости добавить новые.

Единственный момент — класс admin.StackedInline выводит все поля друг под другом и этом занимает много места. В Django admin есть более подходящий класс TabularInline для табличного вывода полей.

Дополнительную информацию по изменеию админки Django можно найти в статье http://itman.in/django-admin-changes/

А нам пора позаботиться о том, что будут отображать основные страницы нашего сайта. Переходим дальше.

Начинаем работу с Django — подключение админки: 9 комментариев

Здравствуйте. После попытки добавить новый «poll» в админке — получаю ошибку:
«»»
no such table: polls_poll

Request Method: POST
Request URL: http://127.0.0.1:8000/admin/polls/poll/add/
Django Version: 1.8.4
Exception Type: OperationalError
Exception Value:
no such table: polls_poll
«»»
К какому из этапов урока мне нужно вернуться?

Виталий, если вы описали модели в models.py, то возможно ві забыли добавить ваше приложение (в случае описанных уроков оно называется polls) в INSTALLED_APPS.

Посмотрите внимательно вывод выполнения команды
python manage.py syncdb
в http://itman.in/django-howto/#_Django-4

Если дело в этом — просто добавьте приложение в список и выполните
python manage.py syncdb повторно.

Чтобы лучше разобраться с работой Django с базами данных и как можно менять таблицы базы после ее создания — рекомендую прочесь http://itman.in/django-db-migration/.

Но это потом, на первом этапе лучше просто удалить базу и создать заново, пока все не будет получаться :)

Была такая же проблема. Оказалось, что начиная с какой-то версии (1.7 или 1.8) команда syncdb удалена, вместо нее необходимо использовать:
python manage.py makemigrations
python manage.py migrate

python manage.py makemigration
python manage.py migrate

Возникла та же проблема, что и у Виталия

OperationalError at /admin/polls/poll/add/
no such table: polls_poll

Не знаю в чём проблема, везде всё прописано и синхронизировано

Попробуй:
python manage.py makemigrations
python manage.py migrate
python manage.py syncdb

Потом restart server

У меня __unicode__ не заработал, пришлось заменить на __str__

Расширяем возможности приложения администрирования Django

Три способа доработки этого мощного приложения для соответствия вашим нуждам

Приложение администрирования Django

Платформа Django предлагает разработчикам множество функциональности: зрелую стандартную библиотеку, активное сообщество пользователей и все преимущества языка Python. В то время как другие инфраструктуры разработки Web-приложений могут предложить то же самое, уникальным достоинством Django является ее встроенное приложение администрирования — admin.

Приложение администрирования предоставляет «из коробки» расширенную функциональность для создания, чтения, обновления и удаления данных (Create-Read-Update-Delete или CRUD), избавляя разработчиков от часов повторяющейся работы. Это является важным как при разработке Web-приложений, потому что с его помощью программисты могут быстро изучать свои модели данных, так и при развертывании приложений, потому что не имеющие отношения к технике конечные пользователи могут пользоваться приложением администрирования для добавления и редактирования содержимого сайта.

В реальной жизни всегда требуется сделать какую-либо подгонку приложения. В документации Django приводится множество руководств по преобразованию базового вида приложения администрирования, а также Django предоставляет несколько простых методов для переопределения части поведения приложения. Но что, если вам нужно больше? С чего начать? В этой статье рассказывается о нескольких направлениях, в которых можно вести серьезную переработку приложения администрирования.

Краткий обзор приложения администрирования

Возможности приложения администрирования с настройками по умолчанию знакомы большинству разработчиков Django. Сделаем краткий обзор этих возможностей. Для начала включим приложение администрирования, отредактировав файл верхнего уровня urls.py, как показано в листинге 1.

Листинг 1. Включаем приложение администрирования в urls.py
Версии ПО, используемые в этой статье
  • Django V1.0.2
  • SQLite V3
  • Python V2.4–2.6 (Django пока не поддерживает Python 3)
  • IPython (для работы в консоли)

Механизм объектно-ориентированного отображения (Object-Relational Mapper или ORM) Django поддерживает множество баз данных, среди которых проще всех в установке sqlite3. Кроме того, sqlite3 поставляется в комплекте со многими ОС. Примеры из этой статьи должны работать с любой базой данных. С полным списком баз данных, поддерживаемых Django, можно ознакомиться в разделе Ресурсы.

Django предоставляет удобный способ настройки рабочего окружения с помощью команды python manage.py shell . Во всех примерах кода, приводимых в этой статье, предполагается, что окружение настраивается именно таким образом.

В терминах Django, в этой статье предполагается следующее:

  • Проект Django называется more_with_admin.
  • В проекте more_with_admin имеется приложение с именем examples.

Приложение examples моделирует простую, похожую на блог систему документов, каждый из которых может иметь комментарии. Все примеры работы в командной строке выполняются из корневой директории проекта more_with_admin.

Также необходимо добавить приложение django.contrib.admin в кортеж settings.INSTALLED_APPS .

Перед тем как двигаться дальше, всем, кто планирует серьезно дорабатывать приложение администрирования, рекомендуется ознакомиться с его исходным кодом. Если позволяет операционная система, может быть полезным создать в директории приложения ярлык или символическую ссылку на приложение администрирования.

Приложение администрирования живет внутри пакета Django. Если вы его установили с помощью setuptools, приложение администрирования должно находиться в директории site-packages/django/contrib/admin. Ниже приводится пример создания в директории проекта символической ссылки, указывающей на исходный код приложения администрирования Django. Вы можете воспользоваться этой ссылкой, изменив ее в соответствии с вашей операционной системой и местонахождением пакета Django.

$ ln -s /path/to/Python/install/site-packages/django/contrib/admin admin-source

Метод admin.autodiscover() пробегается по всем приложениям, указанным в кортеже settings.INSTALLED_APPS и ищет файл с именем admin.py. Он обычно находится на верхнем уровне директории приложения, на одном уровне с models.py.

Приложению examples нужен файл models.py, показанный в листинге 2. Соответствующий файл admin.py приведен ниже.

Листинг 2. Пример файла models.py для этого приложения

Теперь можно запустить сервер разработки Django и взглянуть на приложение администрирования:

По умолчанию приложение администрирования доступно по адресу http://localhost:8000/admin/. Зарегистрировавшись, вы увидите главный экран администратора, показанный на рисунке 1.

Рисунок 1. Главный экран администратора Django
Изменение кода в admin.py

В отличие от остальных файлов приложения Django, если вы при работающем Web-сервере разработки Django вносите изменения в admin.py, то для вступления изменений в силу, возможно, придется вручную перезапустить сервер.

Заметьте, что модели приложения еще недоступны, потому что мы не создали файл admin.py. В листинге 3 показан код, который даст возможность работать с моделями через приложение администрирования.

Листинг 3. Пример файла admin.py

После перезагрузки основной страницы приложения администрирования, как показано на рисунке 2, новые модели становятся доступными для использования.

Рисунок 2. Администратор Django готов работать с пользовательскими моделями данных

Доработка страниц моделей в приложении администрирования

Имена директорий в папках приложения администрирования

Заметьте, что я использую в именах моделей только символы в нижнем регистре. Это согласуется с тем, как работают обычные страницы администратора при генерации адресов URL. В Django эти дружественные для адресов URL имена называются «ленивыми» (slug) именами. Если вы не уверены в том, каким должно быть ленивое имя для определенной модели, перед созданием собственных директорий исследуйте приложение администрирования и посмотрите, какие имена появляются в URL-адресах.

Чтобы понять, как дорабатывать приложение администрирования не меняя исходного кода Django, важно помнить, что мы имеем дело с обычным приложением Django, таким же, как и все остальные. В первую очередь это означает, что к нему применима система наследования шаблонов Django.

В Django шаблоны проекта имеют больший приоритет по сравнению с системными шаблонами. Кроме того, перед обращением к шаблонам по умолчанию приложение администрирования пытается найти жестко закодированные шаблоны с именами, соответствующими каждой модели. Это предоставляет точку входа для доработки приложения.

Сначала отредактируем файл settings.py проекта, указав в нем директорию, в которой Django должен искать шаблоны (листинг 4).

Листинг 4. Добавляем в settings.py директории с шаблонами

Затем создадим в проекте следующие директории:

Приложение администрирования Django сначала попытается найти шаблоны в директории с именем, совпадающим с названием вашего приложения (здесь examples ), затем с названием моделей ( document и comment ) и только потом, в случае неудачи, будет использовать системные шаблоны для отображения страницы.


Переопределяем страницу добавления/удаления экземпляра модели

Для добавления и редактирования экземпляров модели приложение администрирования использует страницу change_form.html. Для начала создадим в директории templates/admin/examples/document/ страницу с именем change_form.html и поместим в нее следующую строку для наследования шаблона Django: <% extends "admin/change_form.html" %>.

Теперь все готово для доработки приложения. Уделите некоторое время знакомству с содержимым реального шаблона admin/change_form.html. Он довольно хорошо организован в блоки, которые можно переопределять, но в некоторых случаях доработка может потребовать «оптового» копирования блоков. Тем не менее, переопределение основанных на блоках шаблонов всегда предпочтительнее копирования страницы целиком.

Какого рода доработку можно сделать на странице добавления/редактирования? Допустим, мы хотим для каждого документа добавить предварительный просмотр пяти последних комментариев.

Сначала создадим тестовые данные(листинг 5).

Листинг 5. Создаем с помощью оболочки Django экземпляр модели Document с несколькими комментариями

Теперь в администраторе на странице списочного отображения показан один документ . Выберем этот документ, чтобы увидеть показанную на рисунке 3 страницу добавления/редактирования по умолчанию.

Рисунок 3. Стандартная страница добавления/редактирования для модели Document

Обратите внимание, что связанные с документом комментарии не показаны вообще. Обычно в приложении администрирования работа с взаимосвязанными моделями организуется посредством классов Inline . Эти мощные классы позволяют пользователям приложения администрирования редактировать или добавлять несколько взаимосвязанных моделей на одной странице. Чтобы увидеть классы Inline в действии, отредактируйте файл admin.py приложения так, как показано в листинге 6.

Листинг 6. Добавляем модель комментария к модели документов в приложении администрирования

На рисунке 4 показан новый вид страницы добавления/редактирования после добавления элемента управления TabularInline .

Рисунок 4. Страница добавления/удаления документа после добавления модели комментария в виде класса Inline

Несомненно, это мощный способ доработки приложения администрирования, однако при нем результат может оказаться слишком громоздким, тогда как мы всего лишь хотели организовать быстрый просмотр комментариев.

В таком случае имеется два подхода. Первый подход – отредактировать HTML-виджеты, ассоциированные с классами inline , с помощью предоставляемого Django интерфейса администрирования виджетов. Виджеты в документации Django описаны весьма подробно. Другой подход — модифицировать шаблон добавления/редактирования напрямую. Этот подход наиболее полезен, если вы вообще не собираетесь использовать специфическую функциональность администратора.

Если вы не хотите разрешать редактировать комментарии (например, потому что пользователи не имеют для этого достаточных прав), но вы хотите, чтобы они могли видеть комментарии, можно модифицировать шаблон change_form.html.

Переменные, предоставляемые приложением администрирования Django

Чтобы добавить функциональность на страницу отображения экземпляра модели, нужно знать, какие данные приложения администрирования уже доступны. В таблице 1 дано описание двух переменных, которые вам в этом помогут.

Таблица 1. Переменные, необходимые для доработки шаблона приложения администрирования
Переменная Описание
object_id Это первичный ключ для редактируемого объекта. Если вы дорабатываете страницу экземпляра какой-либо одной модели (например, документа), это все, что вам понадобится.
content_type_id Если вы переопределяете страницы, работающие с множеством моделей, используйте эту переменную, чтобы опрашивать инфраструктуру ContentTypes для получения имени модели. Больше информации о типах содержимого можно получить в разделе Ресурсы.

Создаем тэг шаблона и включаем его в страницу приложения администрирования

Чтобы вывести комментарии, относящиеся к документу, необходим код, который нельзя вводить непосредственно в шаблон Django. Для таких случаев наилучшим решением является использование тэга шаблона. Сначала создадим директорию тэгов шаблонов и файл __init__.py в ней:

Создадим новый файл с именем examples/templatetags/example_tags.py и добавим в него приведенный ниже код (листинг 7).

Листинг 7. Тэг шаблона для извлечения комментариев к документу с заданным >

Так как здесь используется тэг включения шаблона, необходимо создать соответствующий шаблон: comments.html. Отредактируем файл examples/templates/comments.html file и поместим в него код, показанный в листинге 8.

Листинг 8. Шаблон для предварительного просмотра комментариев

Теперь пришло время добавить это на страницу приложения администрирования. Закомментируйте в admin.py ссылки на CommentInline и сделайте в вашей локальной версии шаблона change_form.html изменения, показанные в листинге 9.

Листинг 9. Включение тэга шаблона в страницу добавления/редактирования

Перед использованием object_id надо проверять, что он существует, так как шаблон change_form.html также используется для создания новых экземпляров модели, при котором object_id экземпляра еще не доступен. Блок after_field_sets – один из многих элементов, предоставляющих возможности для расширения приложения администрирования. Остальные подобные блоки можно найти в исходном коде страницы change_form.html.

На рисунке 5 показана обновленная форма.

Рисунок 5. Страница добавления/редактирования документа после добавления на нее собственного тэга шаблона

Модифицируем поведение приложения администрирования

Как видите, одним только переопределением шаблонов можно добиться довольно многого. Но что, если мы хотим поменять само поведение приложения администрирования? Это можно сделать, подправив исходный код, но тогда вы будете ограничены только той версией Django, которую будете использовать на момент внесения исправлений.

Переопределяем методы в AdminModel

По умолчанию нажатие кнопки Save в приложении администрирования возвращает пользователя на страницу списочного отображения экземпляров модели. Обычно это всех устраивает, но что, если мы хотим переходить сразу на страницу предварительного просмотра объекта, находящуюся вне приложения администрирования? Это распространенное поведение в системах управления содержимым (content management system или CMS).

Метод

В листинге 10 предполагается, что класс Document был изменен и теперь включает в себя метод get_absolute_url() , который является рекомендуемым способом определения моделями Django своего канонического представления. Если метод определен, в администраторе Django на каждой странице этой модели также появляется полезная кнопка View on site.

Большая часть функциональности приложения администрирования реализована в классе admin.ModelAdmin . От этого класса наследуются объекты в admin.py. В нем имеется очень много публичных методов, которые можно переопределять. Определение этого класса можно посмотреть в файле admin-source/options.py.

Есть два способа поменять поведение кнопки Save: можно переопределить метод admin.ModelAdmin.response_add , отвечающий за само перенаправление после сохранения объекта, а также можно переопределить метод admin.ModelAdmin.change_view . Последний способ немного проще.

Листинг 10. Переопределяем страницу, на которую перенаправляются пользователи после сохранения документа

Теперь, когда пользователь нажимает кнопку Save, он перенаправляется на страницу предварительного просмотра сохраненного документа, а не на страницу списочного отображения всех документов.

Добавление функциональности в приложение администрирования с помощью сигналов

Сигналы – это незаслуженно мало используемая функциональность Django, улучшающая модульность вашего кода. Сигналы определяют события, такие как сохранение модели или загрузку шаблона; функции из любого места проекта Django могут узнавать о событиях и отвечать на них. Это означает, что вы можете легко расширить поведение приложения, не изменяя приложение напрямую.

В приложении администрирования имеется функциональность, которую разработчики желают поменять особенно часто – это управление пользователями с помощью класса django.contrib.auth.models.User . Часто приложение администрирования является единственным местом, где добавляются или модифицируются пользователи Django, что делает сложной доработку под себя этого полезного класса.

Представим, что мы хотим, чтобы администратор сайта получал уведомление по электронной почте каждый раз при создании нового объекта класса User . Так как модель User напрямую недоступна в проекте, может показаться, что реализовать это можно либо создав класс-наследник User , либо каким-нибудь неявным методом, например с помощью создания некого фиктивного профиля для модификации.

В листинге 11 демонстрируется, как легко добавить функцию, выполняющуюся при каждом сохранении экземпляра класса User . Сигналы обычно добавляют в models.py.

Листинг 11. Использование сигналов Django для уведомления о создании новых пользователей

Сигнал post_save предоставляется Django, он генерируется каждый раз при создании или сохранении экземпляра модели. Метод connect() здесь принимает два аргумента: функцию обратного вызова ( notify_admin ) и аргумент sender , который сообщает о том, что эту функцию следует вызывать только при сохранении экземпляров модели User .

Внутрь функции обратного вызова сигнал post_save передает отправителя (класс модели), экземпляр этой модели и булево значение, обозначающее, был ли этот экземпляр только что создан. В этом примере метод посылает электронное сообщение только при создании нового экземпляра модели User ; в противном случае не делается ничего.

В разделе Ресурсы можно ознакомиться со списком предоставляемых Django сигналов, а также с документацией по созданию собственных сигналов.

Более глубокие изменения: добавляем права строкового уровня

Почему ?

Возможно, не сразу становится понятным, почему поле ForeignKey будет выставляться с флагом blank=True , когда оно не является текстовым полем. В данном случае это так потому, что приложение администрирования использует blank вместо null , чтобы определять, должно ли значение быть выставлено вручную перед сохранением модели.

Если задать только null=True или вообще ничего, то приложение администрирования Django перед сохранением заставит пользователя вручную выбрать значение «added by», хотя вместо этого мы хотим, чтобы при сохранении по умолчанию выбирался текущий пользователь.

Для приложения администрирования Django часто дополнительно запрашивают добавление в систему прав пользователей прав строкового уровня. По умолчанию администратор обеспечивает детальное управление ролями и правами пользователей, но эти роли применяются на уровне классов: пользователь может модифицировать либо все экземпляры модели Document, либо никаких.

В ряде случаев хочется разрешить пользователям изменять только какие-либо специфичные объекты. Такие права часто называют правами строкового уровня, так как они отражают способность изменять только некоторые строки в таблице базы данных вместо права изменять любые записи в таблице без ограничений. Например, в приложении examples можно разрешить пользователям видеть только их собственные документы.

Сначала, как показано в листинге 12, добавим в models.py атрибут, в котором будет храниться имя создателя экземпляра модели Document .

Листинг 12. Добавляем в models.py информацию о пользователе, создавшем каждый экземпляр модели Document

Затем нужно добавить код для автоматического заполнения этого поля при создании экземпляра модели Document . Сигналы в этом случае не подходят, так как они не имеют доступа к объекту пользователя. Однако класс ModelAdmin предоставляет метод, включающий в себя запрос, а значит, как параметр, и текущего пользователя.

Поменяем метод save_model() в файле admin.py так, как показано в листинге 13.

Листинг 13. Переопределяем метод в DocumentAdmin для сохранения текущего пользователя в базу данных при создании экземпляра модели

Если атрибут added_by равен None , значит это новая запись, которая раньше не сохранялась. (Также можно проверять, что change равно false , это обозначает, что запись добавляется, но проверка пустоты поля added_by обеспечивает, что будут заполняться и записи, которые были добавлены не из приложения администрирования.)

Далее надо ограничить список документов, доступных пользователю, только документами, созданными этим пользователем. Это можно сделать с помощью находящегося в классе ModelAdmin метода queryset() , который определяет результат запроса, по умолчанию возвращаемый любой страницей списочного отображения.

Переопределим метод queryset() так, как показано в листинге 14, чтобы ограничить список только документами, созданными текущим пользователем. Суперпользователи могут видеть все документы.

Листинг 14. Переопределяем результат запроса, возвращаемый списочными страницами

Теперь все запросы к странице списочного отображения модели Document приложения администрирования будут показывать только документы, созданные текущим пользователем (за исключением суперпользователей, которым показываются все документы).

Конечно, на данный момент ничто не мешает находчивому пользователю получить доступ к странице редактирования чужого документа, зная его ID. По-настоящему безопасные права строкового уровня требуют переопределения большего количества методов. Так как пользователи с правами администратора, как правило, пользуются определенным доверием, иногда оказывается достаточно такой простой системы прав для обеспечения хорошо налаженного рабочего процесса.

Заключение

Для доработки приложения администрирования требуются некоторые знания исходного кода приложения, но править его приходится лишь в незначительной степени. Приложение администрирования структурировано так, чтобы быть расширяемым посредством обычного наследования Python и некоторой специфичной для Django функциональности, такой как сигналы.

Доработка под свои нужды существующего приложения администрирования имеет много преимуществ по сравнению с созданием нового интерфейса администрирования:

  • ваше приложение может выиграть от развития проекта Django по мере продолжения его активной разработки;
  • приложение администрирования уже поддерживает большинство типичных сценариев использования;
  • при добавлении в проект нового приложения оно так же, как и ваш собственный код, автоматически будет доступно для администрирования.

В Django версии 1.1 в приложении администрирования будут добавлены две часто запрашиваемые новые возможности: возможность линейного (inline) редактирования полей на страницах списочного просмотра и действия администратора (admin actions), которые позволяют обновлять за один раз множество объектов. Оба добавления устранят необходимость писать эту функциональность с нуля при расширении и доработке приложения

Ресурсы для скачивания

Похожие темы

  • Оригинал статьи: Doing more with the Django admin (EN).
  • Разработчикам, которые только начинают знакомиться с Django или приложением администрирования, следует начать с руководства Django (EN).
  • Главная страница документации приложения администрирования и исходный код приложения администрирования являются самым лучшим и полным справочником по этому приложению (EN).
  • Ознакомьтесь со списком сигналов, предоставляемых Django, и документацией по созданию собственных сигналов (EN).
  • Узнайте о двух новых возможностях приложения администрирования в Django версии 1.1: действиях администратора и редактируемых списках (EN).
  • В этой статье демонстрировалось редактирование страниц, специфичных для одной модели. Если вам нужно редактировать страницы, относящиеся к нескольким моделям, ознакомьтесь с имеющейся в Django инфраструктурой contenttypes (EN).
  • В документации Django содержится полный список баз данных, поддерживаемых Django. Начиная с версии 1.0, в Django также появилась возможность добавлять поддержку новых баз данных (EN).
  • Узнайте больше об изменении механизма перенаправления запросов в приложении администрирования (EN).
  • Многие дистрибутивы Linux®, а также Mac OS® X имеют в своем комплекте SQLite, однако если его нет в вашей системе, вы можете загрузить его с сайта проекта SQLite (EN).
  • SQLite V3: Начиная с версии 2.5, в Python появилась поддержка SQLite 3 без необходимости в дополнительных драйверах. В ранних версиях Python для этого приходилось загружать пакет pysqlite (EN).
  • Интервью и дискуссии разработчиков в подкастах developerWorks (EN).
  • Следите за developerWorks в Twitter (EN).
  • Разработайте ваш следующий проект с помощью пробного ПО от IBM, доступного для загрузки и на DVD.(EN)
  • Загрузите ознакомительные версии продуктов IBM или поработайте с онлайновой пробной версией IBM SOA Sandbox и получите практический опыт с инструментами разработки и связующим ПО от DB2®, Lotus®, Rational®, Tivoli® и WebSphere®.(EN)

Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

djangocms-admin-style 1.4.0

pip install djangocms-admin-style Copy PIP instructions

Last released: Apr 15, 2020

Adds pretty CSS styles for the django CMS admin interface.

Statistics

View statistics for this project via Libraries.io, or by using Google BigQuery

License: BSD License (BSD)

Author: Divio AG

Maintainers

Classifiers

  • Development Status
    • 5 — Production/Stable


  • Environment
    • Web Environment
  • Framework
    • Django
    • Django :: 1.11
    • Django :: 2.1
    • Django :: 2.2
  • Intended Audience
    • Developers
  • License
    • OSI Approved :: BSD License
  • Operating System
    • OS Independent
  • Programming Language
    • Python
    • Python :: 2
    • Python :: 2.7
    • Python :: 3
    • Python :: 3.4
    • Python :: 3.5
    • Python :: 3.6
    • Python :: 3.7
  • Topic
    • Internet :: WWW/HTTP
    • Internet :: WWW/HTTP :: Dynamic Content
    • Software Development
    • Software Development :: Libraries

Project description

Adds pretty CSS styles for the django CMS admin interface.

The shortcuts you see on top of the dashboard are from django-admin-shortcuts

Contributing

This is a an open-source project. We’ll be delighted to receive your feedback in the form of issues and pull requests. Before submitting your pull request, please review our contribution guidelines.

We’re grateful to all contributors who have helped create and maintain this package. Contributors are listed at the contributors section.

One of the easiest contributions you can make is helping to translate this addon on Transifex.

Documentation

See REQUIREMENTS in the setup.py file for additional dependencies:

Installation

For a manual install:

  • run pip install djangocms-admin-style
  • add djangocms_admin_style to your INSTALLED_APPS just before 'django.contrib.admin'
  • run python manage.py migrate djangocms_admin_style

Configuration

The django CMS Admin Style overrides django admin’s base_site.html, but you can still partially customize this page. Look at the source of templates/admin/base_site.html and override the templates that are included in various blocks. For example, you can add your own CSS in templates/admin/inc/extrastyle.html.

The following additional settings can be set:

  • CMS_ENABLE_UPDATE_CHECK = True Set to False to disable the update notification.
  • CMS_UPDATE_CHECK_TYPE = ('minor') Set to ('patch') to get only patch notifications. (minor = 3.x.x, patch = 3.4.x)

The update checker does not gather or record any data.

To compile CSS run the following commands:

For further options have a look at the gulpfile.js.

Running Tests

In order to run integration tests you need to have Docker installed.

You can run tests by executing:

The integration tests are written using Casperjs, phantomcss and djangocms-casper-helpers.

Documentation

The Django admin site¶

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin’s recommended use is limited to an organization’s internal management tool. It’s not intended for building your entire front end around.

The admin has many hooks for customization, but beware of trying to use those hooks exclusively. If you need to provide a more process-centric interface that abstracts away the implementation details of database tables and fields, then it’s probably time to write your own views.

In this document we discuss how to activate, use, and customize Django’s admin interface.

Overview¶

The admin is enabled in the default project template used by startproject .

If you’re not using the default project template, here are the requirements:

After you’ve taken these steps, you’ll be able to use the admin site by visiting the URL you hooked it into ( /admin/ , by default).

If you need to create a user to login with, use the createsuperuser command. By default, logging in to the admin requires that the user has the is_superuser or is_staff attribute set to True .

Finally, determine which of your application’s models should be editable in the admin interface. For each of those models, register them with the admin as described in ModelAdmin .

Other topics¶

For information about serving the static files (images, JavaScript, and CSS) associated with the admin in production, see Serving files .

Having problems? Try FAQ: The admin .

ModelAdmin objects¶

The ModelAdmin > admin.py in your application. Let’s take a look at a very simple example of the ModelAdmin :

Do you need a ModelAdmin object at all?

In the preceding example, the ModelAdmin > ModelAdmin object at all – you can register the model > ModelAdmin description. The preceding example could be simplified to:

The register decorator¶

There is also a decorator for registering your ModelAdmin classes:

It’s given one or more model > ModelAdmin . If you’re using a custom AdminSite , pass it using the site keyword argument:

You can’t use this decorator if you have to reference your model admin > __init__() method, e.g. super(PersonAdmin, self).__init__(*args, **kwargs) . You can use super().__init__(*args, **kwargs) .

Discovery of admin files¶

When you put ‘django.contrib.admin’ in your INSTALLED_APPS setting, Django automatically looks for an admin module in each application and imports it.

A dotted import path to the default admin site’s > ‘django.contrib.admin.sites.AdminSite’ . See Overriding the default admin site for usage.

This function attempts to import an admin module in each installed application. Such modules are expected to register models with the admin.

Typically you won’t need to call this function directly as AdminConfig calls it when Django starts.

If you are using a custom AdminSite , it is common to import all of the ModelAdmin sub > AdminSite . In that case, in order to disable auto-discovery, you should put ‘django.contrib.admin.apps.SimpleAdminConfig’ instead of ‘django.contrib.admin’ in your INSTALLED_APPS setting.

ModelAdmin options¶

The ModelAdmin is very flexible. It has several options for dealing with customizing the interface. All options are defined on the ModelAdmin subclass:

A list of actions to make available on the change list page. See Admin actions for details.

ModelAdmin. actions_on_top ¶ ModelAdmin. actions_on_bottom ¶

Controls where on the page the actions bar appears. By default, the admin changelist displays actions at the top of the page ( actions_on_top = True; actions_on_bottom = False ).

Controls whether a selection counter is displayed next to the action dropdown. By default, the admin changelist will display it ( actions_selection_counter = True ).

Set date_hierarchy to the name of a DateField or DateTimeField in your model, and the change list page will include a date-based drilldown navigation by that field.

You can also specify a field on a related model using the __ lookup, for example:

This will intelligently populate itself based on available data, e.g. if all the dates are in one month, it’ll show the day-level drill-down only.

date_hierarchy uses QuerySet.datetimes() internally. Please refer to its documentation for some caveats when time zone support is enabled ( USE_TZ = True ).

This attribute overr > None , empty string, etc.). The default value is — (a dash). For example:

You can also overr > empty_value_display for all admin pages with AdminSite.empty_value_display , or for specific fields like this:

This attribute, if given, should be a list of field names to exclude from the form.

For example, let’s consider the following model:

If you want a form for the Author model that includes only the name and title fields, you would specify fields or exclude like this:

Since the Author model only has three fields, name , title , and birth_date , the forms resulting from the above declarations will contain exactly the same fields.

Use the fields option to make simple layout changes in the forms on the “add” and “change” pages such as showing only a subset of available fields, modifying their order, or grouping them into rows. For example, you could define a simpler version of the admin form for the django.contrib.flatpages.models.FlatPage model as follows:

In the above example, only the fields url , title and content will be displayed, sequentially, in the form. fields can contain values defined in ModelAdmin.readonly_fields to be displayed as read-only.

For more complex layout needs, see the fieldsets option.

The fields option accepts the same types of values as list_display , except that callables aren’t accepted. Names of model and model admin methods will only be used if they’re listed in readonly_fields .

To display multiple fields on the same line, wrap those fields in their own tuple. In this example, the url and title fields will display on the same line and the content field will be displayed below them on its own line:

This fields option should not be confused with the fields dictionary key that is within the fieldsets option, as described in the next section.

If neither fields nor fieldsets options are present, Django will default to displaying each field that isn’t an AutoField and has editable=True , in a single fieldset, in the same order as the fields are defined in the model.

Set fieldsets to control the layout of admin “add” and “change” pages.

fieldsets is a list of two-tuples, in which each two-tuple represents a on the admin form page. (A is a “section” of the form.)

The two-tuples are in the format (name, field_options) , where name is a string representing the title of the fieldset and field_options is a dictionary of information about the fieldset, including a list of fields to be displayed in it.

This results in an admin page that looks like:

If neither fieldsets nor fields options are present, Django will default to displaying each field that isn’t an AutoField and has editable=True , in a single fieldset, in the same order as the fields are defined in the model.

The field_options dictionary can have the following keys:

A tuple of field names to display in this fieldset. This key is required.

As with the fields option, to display multiple fields on the same line, wrap those fields in their own tuple. In this example, the first_name and last_name fields will display on the same line:

fields can contain values defined in readonly_fields to be displayed as read-only.

If you add the name of a callable to fields , the same rule applies as with the fields option: the callable must be listed in readonly_fields .

A list or tuple containing extra CSS classes to apply to the fieldset.

Two useful > collapse and wide . Fieldsets with the collapse style will be initially collapsed in the admin and replaced with a small “click to expand” link. Fieldsets with the wide style will be given extra horizontal space.

A string of optional extra text to be displayed at the top of each fieldset, under the heading of the fieldset. This string is not rendered for TabularInline due to its layout.

Note that this value is not HTML-escaped when it’s displayed in the admin interface. This lets you include HTML if you so desire. Alternatively you can use plain text and django.utils.html.escape() to escape any HTML special characters.


Same as filter_horizontal , but uses a vertical display of the filter interface with the box of unselected options appearing above the box of selected options.

If you define the Meta.model attribute on a ModelForm , you must also define the Meta.fields attribute (or the Meta.exclude attribute). However, since the admin has its own way of defining fields, the Meta.fields attribute will be ignored.

If the ModelForm is only going to be used for the admin, the easiest solution is to omit the Meta.model attribute, since ModelAdmin will prov > fields = [] in the Meta > ModelForm .

If your ModelForm and ModelAdmin both define an exclude option then ModelAdmin takes precedence:

In the above example, the “age” field will be excluded but the “name” field will be included in the generated form.

This prov > Field options for use in the admin. formfield_overrides is a dictionary mapping a field class to a dict of arguments to pass to the field at construction time.

Since that’s a bit abstract, let’s look at a concrete example. The most common use of formfield_overrides is to add a custom w > RichTextEditorWidget that we’d like to use for large text fields instead of the default

. Here’s how we’d do that:

Note that the key in the dictionary is the actual field > __init__() method. See The Forms API for details.

If you want to use a custom w > ForeignKey or ManyToManyField ), make sure you haven’t included that field’s name in raw_id_fields , radio_fields , or autocomplete_fields .

formfield_overrides won’t let you change the w > raw_id_fields , radio_fields , or autocomplete_fields set. That’s because raw_id_fields , radio_fields , and autocomplete_fields imply custom widgets of their own.

Set list_display to control which fields are displayed on the change list page of the admin.

If you don’t set list_display , the admin site will display a single column that displays the __str__() representation of each object.

There are four types of values that can be used in list_display :

The name of a model field. For example:

A callable that accepts one argument, the model instance. For example:

A string representing a ModelAdmin method that accepts one argument, the model instance. For example:

A string representing a model attribute or method (without any required arguments). For example:

A few special cases to note about list_display :

If the field is a ForeignKey , Django will display the __str__() of the related object.

ManyToManyField fields aren’t supported, because that would entail executing a separate SQL statement for each row in the table. If you want to do this nonetheless, give your model a custom method, and add that method’s name to list_display . (See below for more on custom methods in list_display .)

If the field is a BooleanField , Django will display a pretty “on” or “off” icon instead of True or False .

If the string given is a method of the model, ModelAdmin or a callable, Django will HTML-escape the output by default. To escape user input and allow your own unescaped tags, use format_html() .

Here’s a full example model:

As some examples have already demonstrated, when using a callable, a model method, or a ModelAdmin method, you can customize the column’s title by adding a short_description attribute to the callable.

Or on a field level:

If the string given is a method of the model, ModelAdmin or a callable that returns True or False Django will display a pretty “on” or “off” icon if you give the method a boolean attribute whose value is True .

Here’s a full example model:

The __str__() method is just as val > list_display as any other model method, so it’s perfectly OK to do this:

Usually, elements of list_display that aren’t actual database fields can’t be used in sorting (because Django does all the sorting at the database level).

However, if an element of list_display represents a certain database field, you can indicate this fact by setting the admin_order_field attribute of the item.

The above will tell Django to order by the first_name field when trying to sort by colored_first_name in the admin.

To indicate descending order with admin_order_field you can use a hyphen prefix on the field name. Using the above example, this would look like:

admin_order_field supports query lookups to sort by values on related models. This example includes an “author first name” column in the list display and allows sorting it by first name:

Query expressions may be used in admin_order_field . For example:

Support for expressions in admin_order_field was added.

Elements of list_display can also be properties. Please note however, that due to the way properties work in Python, setting short_description on a property is only possible when using the property() function and not with the @property decorator.

The field names in list_display will also appear as CSS > column- on each

element. This can be used to set column widths in a CSS file for example.

Django will try to interpret every element of list_display in this order:

  • A field of the model.
  • A callable.
  • A string representing a ModelAdmin attribute.
  • A string representing a model attribute.

For example if you have first_name as a model field and as a ModelAdmin attribute, the model field will be used.

Use list_display_links to control if and which fields in list_display should be linked to the “change” page for an object.

By default, the change list page will link the first column – the first field specified in list_display – to the change page for each item. But list_display_links lets you change this:

Set it to None to get no links at all.

Set it to a list or tuple of fields (in the same format as list_display ) whose columns you want converted to links.

You can specify one or many fields. As long as the fields appear in list_display , Django doesn’t care how many (or how few) fields are linked. The only requirement is that if you want to use list_display_links in this fashion, you must define list_display .

In this example, the first_name and last_name fields will be linked on the change list page:

In this example, the change list page grid will have no links:

Set list_editable to a list of field names on the model which will allow editing on the change list page. That is, fields listed in list_editable will be displayed as form widgets on the change list page, allowing users to edit and save multiple rows at once.

list_editable interacts with a couple of other options in particular ways; you should note the following rules:

  • Any field in list_editable must also be in list_display . You can’t edit a field that’s not displayed!
  • The same field can’t be listed in both list_editable and list_display_links – a field can’t be both a form and a link.

You’ll get a validation error if either of these rules are broken.

Set list_filter to activate filters in the right sidebar of the change list page of the admin, as illustrated in the following screenshot:

list_filter should be a list or tuple of elements, where each element should be of one of the following types:

a field name, where the specified field should be either a BooleanField , CharField , DateField , DateTimeField , IntegerField , ForeignKey or ManyToManyField , for example:

Field names in list_filter can also span relations using the __ lookup, for example:

a > django.contrib.admin.SimpleListFilter , which you need to prov > title and parameter_name attributes to and overr > lookups and queryset methods, e.g.:

As a convenience, the HttpRequest object is passed to the lookups and queryset methods, for example:

Also as a convenience, the ModelAdmin object is passed to the lookups method, for example if you want to base the lookups on the available data:

a tuple, where the first element is a field name and the second element is a > django.contrib.admin.FieldListFilter , for example:

You can limit the choices of a related model to the objects involved in that relation using RelatedOnlyFieldListFilter :

Assuming author is a ForeignKey to a User model, this will limit the list_filter choices to the users who have written a book instead of listing all users.

The FieldListFilter API is considered internal and might be changed.

List filter’s typically appear only if the filter has more than one choice. A filter’s has_output() method controls whether or not it appears.

It is possible to specify a custom template for rendering a list filter:

See the default template prov > admin/filter.html ) for a concrete example.

Set list_max_show_all to control how many items can appear on a “Show all” admin change list page. The admin will display a “Show all” link on the change list only if the total result count is less than or equal to this setting. By default, this is set to 200 .

Set list_per_page to control how many items appear on each paginated admin change list page. By default, this is set to 100 .

Set list_select_related to tell Django to use select_related() in retrieving the list of objects on the admin change list page. This can save you a bunch of database queries.

The value should be either a boolean, a list or a tuple. Default is False .

When value is True , select_related() will always be called. When value is set to False , Django will look at list_display and call select_related() if any ForeignKey is present.

If you need more fine-grained control, use a tuple (or list) as value for list_select_related . Empty tuple will prevent Django from calling select_related at all. Any other tuple will be passed directly to select_related as parameters. For example:

will call select_related(‘author’, ‘category’) .

If you need to specify a dynamic value based on the request, you can implement a get_list_select_related() method.

ModelAdmin ignores this attribute when select_related() was already called on the changelist’s QuerySet .

Set ordering to specify how lists of objects should be ordered in the Django admin views. This should be a list or tuple in the same format as a model’s ordering parameter.

If this isn’t provided, the Django admin will use the model’s default ordering.

If you need to specify a dynamic order (for example depending on user or language) you can implement a get_ordering() method.

Performance considerations with ordering and sorting

To ensure a deterministic ordering of results, the changelist adds pk to the ordering if it can’t find a single or unique together set of fields that provide total ordering.

For example, if the default ordering is by a non-unique name field, then the changelist is sorted by name and pk . This could perform poorly if you have a lot of rows and don’t have an index on name and pk .

The paginator > django.core.paginator.Paginator is used. If the custom paginator > django.core.paginator.Paginator , you will also need to prov > ModelAdmin.get_paginator() .

Set prepopulated_fields to a dictionary mapping field names to the fields it should prepopulate from:

When set, the given fields will use a bit of JavaScript to populate from the fields assigned. The main use for this functionality is to automatically generate the value for SlugField fields from one or more other fields. The generated value is produced by concatenating the values of the source fields, and then by transforming that result into a valid slug (e.g. substituting dashes for spaces; lowercasing ASCII letters; and removing various English stop words such as ‘a’, ‘an’, ‘as’, and similar).

Prepopulated fields aren’t modified by JavaScript after a value has been saved. It’s usually undesired that slugs change (which would cause an object’s URL to change if the slug is used in it).

prepopulated_fields doesn’t accept DateTimeField , ForeignKey , OneToOneField , and ManyToManyField fields.

The admin now preserves filters on the list view after creating, editing or deleting an object. You can restore the previous behavior of clearing filters by setting this attribute to False .

By default, Django’s admin uses a select-box interface ( ) for fields that are ForeignKey or have choices set. If a field is present in radio_fields , Django will use a radio-button interface instead. Assuming group is a ForeignKey on the Person model:

You have the choice of using HORIZONTAL or VERTICAL from the django.contrib.admin module.

Don’t include a field in radio_fields unless it’s a ForeignKey or has choices set.

autocomplete_fields is a list of ForeignKey and/or ManyToManyField fields you would like to change to Select2 autocomplete inputs.

By default, the admin uses a select-box interface ( ) for those fields. Sometimes you don’t want to incur the overhead of selecting all the related instances to display in the dropdown.

The Select2 input looks similar to the default input but comes with a search feature that loads the options asynchronously. This is faster and more user-friendly if the related model has many instances.

You must define search_fields on the related object’s ModelAdmin because the autocomplete search uses it.

To avo > view or change permission to the related object in order to use autocomplete.

Ordering and pagination of the results are controlled by the related ModelAdmin ’s get_ordering() and get_paginator() methods.

In the following example, ChoiceAdmin has an autocomplete field for the ForeignKey to the Question . The results are filtered by the question_text field and ordered by the date_created field:

Performance considerations for large datasets

Ordering using ModelAdmin.ordering may cause performance problems as sorting on a large queryset will be slow.

Also, if your search fields include fields that aren’t indexed by the database, you might encounter poor performance on extremely large tables.

You may also want to change the Paginator on very large tables as the default paginator always performs a count() query. For example, you could overr > Paginator.count property.

By default, Django’s admin uses a select-box interface ( ) for fields that are ForeignKey . Sometimes you don’t want to incur the overhead of having to select all the related instances to display in the drop-down.

raw_id_fields is a list of fields you would like to change into an Input w > ForeignKey or ManyToManyField :


The raw_id_fields Input w > ForeignKey or a comma separated list of values if the field is a ManyToManyField . The raw_id_fields widget shows a magnifying glass button next to the field which allows users to search for and select a value:

By default the admin shows all fields as editable. Any fields in this option (which should be a list or tuple ) will display its data as-is and non-editable; they are also excluded from the ModelForm used for creating and editing. Note that when specifying ModelAdmin.fields or ModelAdmin.fieldsets the read-only fields must be present to be shown (they are ignored otherwise).

If readonly_fields is used without defining explicit ordering through ModelAdmin.fields or ModelAdmin.fieldsets they will be added last after all editable fields.

A read-only field can not only display data from a model’s field, it can also display the output of a model’s method or a method of the ModelAdmin > ModelAdmin.list_display behaves. This provides an easy way to use the admin interface to provide feedback on the status of the objects being edited, for example:

Set save_as to enable a “save as new” feature on admin change forms.

Normally, objects have three save options: “Save”, “Save and continue editing”, and “Save and add another”. If save_as is True , “Save and add another” will be replaced by a “Save as new” button that creates a new object (with a new ID) rather than updating the existing object.

By default, save_as is set to False .

When save_as=True , the default redirect after saving the new object is to the change view for that object. If you set save_as_continue=False , the redirect will be to the changelist view.

By default, save_as_continue is set to True .

Set save_on_top to add save buttons across the top of your admin change forms.

Normally, the save buttons appear only at the bottom of the forms. If you set save_on_top , the buttons will appear both on the top and the bottom.

By default, save_on_top is set to False .

Set search_fields to enable a search box on the admin change list page. This should be set to a list of field names that will be searched whenever somebody submits a search query in that text box.

These fields should be some kind of text field, such as CharField or TextField . You can also perform a related lookup on a ForeignKey or ManyToManyField with the lookup API “follow” notation:

For example, if you have a blog entry with an author, the following definition would enable searching blog entries by the email address of the author:

When somebody does a search in the admin search box, Django splits the search query into words and returns all objects that contain each of the words, case-insensitive (using the icontains lookup), where each word must be in at least one of search_fields . For example, if search_fields is set to [‘first_name’, ‘last_name’] and a user searches for john lennon , Django will do the equivalent of this SQL WHERE clause:

If you don’t want to use icontains as the lookup, you can use any lookup by appending it the field. For example, you could use exact by setting search_fields to [‘first_name__exact’] .

Beware that because query terms are split and ANDed as described earlier, searching with exact only works with a single search word since two or more words can’t all be an exact match unless all words are the same.

The ability to specify a field lookup was added.

Some (older) shortcuts for specifying a field lookup are also available. You can prefix a field in search_fields with the following characters and it’s equivalent to adding __ to the field:

Prefix Lookup
^ startswith
= iexact
@ search
None icontains

If you need to customize search you can use ModelAdmin.get_search_results() to provide additional or alternate search behavior.

Set show_full_result_count to control whether the full count of objects should be displayed on a filtered admin page (e.g. 99 results (103 total) ). If this option is set to False , a text like 99 results (Show all) is displayed instead.

The default of show_full_result_count=True generates a query to perform a full count on the table which can be expensive if the table contains a large number of rows.

By default, the change list page allows sorting by all model fields (and callables that have the admin_order_field property) specified in list_display .

If you want to disable sorting for some columns, set sortable_by to a collection (e.g. list , tuple , or set ) of the subset of list_display that you want to be sortable. An empty collection disables sorting for all columns.

If you need to specify this list dynamically, implement a get_sortable_by() method instead.

Set view_on_site to control whether or not to display the “View on site” link. This link should bring you to a URL where you can display the saved object.

This value can be either a boolean flag or a callable. If True (the default), the object’s get_absolute_url() method will be used to generate the url.

If your model has a get_absolute_url() method but you don’t want the “View on site” button to appear, you only need to set view_on_site to False :

In case it is a callable, it accepts the model instance as a parameter. For example:

Custom template options¶

Path to a custom template, used by add_view() .

Path to a custom template, used by change_view() .

Path to a custom template, used by changelist_view() .

Path to a custom template, used by delete_view() for displaying a confirmation page when deleting one or more objects.

Path to a custom template, used by the delete_selected action method for displaying a confirmation page when deleting one or more objects. See the actions documentation .

Path to a custom template, used by history_view() .

ModelAdmin methods¶

When overr > ModelAdmin.save_model() and ModelAdmin.delete_model() , your code must save/delete the object. They aren’t meant for veto purposes, rather they allow you to perform extra operations.

The save_model method is given the HttpRequest , a model instance, a ModelForm instance, and a boolean value based on whether it is adding or changing the object. Overr > super().save_model() to save the object using Model.save() .

For example to attach request.user to the object prior to saving:

The delete_model method is given the HttpRequest and a model instance. Overr > super().delete_model() to delete the object using Model.delete() .

ModelAdmin. delete_queryset (request, queryset) [source] ¶

The save_formset method is given the HttpRequest , the parent ModelForm instance and a boolean value based on whether it is adding or changing the parent object.

For example, to attach request.user to each changed formset model instance:

ModelAdmin. get_ordering (request

The get_ordering method takes a request as parameter and is expected to return a list or tuple for ordering similar to the ordering attribute. For example:

The get_search_results method modifies the list of objects displayed into those that match the provided search term. It accepts the request, a queryset that applies the current filters, and the user-provided search term. It returns a tuple containing a queryset modified to implement the search, and a boolean indicating if the results may contain duplicates.

The default implementation searches the fields named in ModelAdmin.search_fields .

This method may be overr > True in the second element of the return value.

For example, to search by name and age , you could use:

This implementation is more efficient than search_fields = (‘name’, ‘=age’) which results in a string comparison for the numeric field, for example . OR UPPER(«polls_choice».»votes»::text) = UPPER(‘4’) on PostgreSQL.

The save_related method is given the HttpRequest , the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed. Here you can do any pre- or post-save operations for objects related to the parent. Note that at this point the parent object and its form have already been saved.

ModelAdmin. get_autocomplete_fields (request

ModelAdmin. get_readonly_fields (request, obj=None

The get_readonly_fields method is given the HttpRequest and the obj being edited (or None on an add form) and is expected to return a list or tuple of field names that will be displayed as read-only, as described above in the ModelAdmin.readonly_fields section.

ModelAdmin. get_prepopulated_fields (request, obj=None

The get_prepopulated_fields method is given the HttpRequest and the obj being edited (or None on an add form) and is expected to return a dictionary , as described above in the ModelAdmin.prepopulated_fields section.

ModelAdmin. get_list_display (request) [source] ¶

The get_list_display method is given the HttpRequest and is expected to return a list or tuple of field names that will be displayed on the changelist view as described above in the ModelAdmin.list_display section.

ModelAdmin. get_list_display_links (request, list_display) [source] ¶

The get_list_display_links method is given the HttpRequest and the list or tuple returned by ModelAdmin.get_list_display() . It is expected to return either None or a list or tuple of field names on the changelist that will be linked to the change view, as described in the ModelAdmin.list_display_links section.

ModelAdmin. get_exclude (request, obj=None

The get_exclude method is given the HttpRequest and the obj being edited (or None on an add form) and is expected to return a list of fields, as described in ModelAdmin.exclude .

ModelAdmin. get_fields (request, obj=None

The get_fields method is given the HttpRequest and the obj being edited (or None on an add form) and is expected to return a list of fields, as described above in the ModelAdmin.fields section.

ModelAdmin. get_fieldsets (request, obj=None

The get_fieldsets method is given the HttpRequest and the obj being edited (or None on an add form) and is expected to return a list of two-tuples, in which each two-tuple represents a on the admin form page, as described above in the ModelAdmin.fieldsets section.

ModelAdmin. get_list_filter (request) [source] ¶

The get_list_filter method is given the HttpRequest and is expected to return the same kind of sequence type as for the list_filter attribute.

ModelAdmin. get_list_select_related (request) [source] ¶

The get_list_select_related method is given the HttpRequest and should return a boolean or list as ModelAdmin.list_select_related does.

ModelAdmin. get_search_fields (request) [source] ¶

The get_search_fields method is given the HttpRequest and is expected to return the same kind of sequence type as for the search_fields attribute.

ModelAdmin. get_sortable_by (request

The get_sortable_by() method is passed the HttpRequest and is expected to return a collection (e.g. list , tuple , or set ) of field names that will be sortable in the change list page.

Its default implementation returns sortable_by if it’s set, otherwise it defers to get_list_display() .

For example, to prevent one or more columns from being sortable:

The get_inline_instances method is given the HttpRequest and the obj being edited (or None on an add form) and is expected to return a list or tuple of InlineModelAdmin objects, as described below in the InlineModelAdmin section. For example, the following would return inlines without the default filtering based on add, change, delete, and view permissions:

If you overr > inlines or you might encounter a “Bad Request” error when adding related objects.

The get_urls method on a ModelAdmin returns the URLs to be used for that ModelAdmin in the same way as a URLconf. Therefore you can extend them as documented in URL dispatcher :

If you want to use the admin layout, extend from admin/base_site.html :

Notice that the custom patterns are included before the regular admin URLs: the admin URL patterns are very permissive and will match nearly anything, so you’ll usually want to prepend your custom URLs to the built-in ones.

In this example, my_view will be accessed at /admin/myapp/mymodel/my_view/ (assuming the admin URLs are included at /admin/ .)

However, the self.my_view function registered above suffers from two problems:

  • It will not perform any permission checks, so it will be accessible to the general public.
  • It will not provide any header details to prevent caching. This means if the page retrieves data from the database, and caching middleware is active, the page could show outdated information.

Since this is usually not what you want, Django prov > AdminSite.admin_view() (i.e. self.admin_site.admin_view ins > ModelAdmin instance); use it like so:

Notice the wrapped view in the fifth line above:

This wrapping will protect self.my_view from unauthorized access and will apply the django.views.decorators.cache.never_cache() decorator to make sure it is not cached if the cache middleware is active.

If the page is cacheable, but you still want the permission check to be performed, you can pass a cacheable=True argument to AdminSite.admin_view() :

ModelAdmin views have model_admin attributes. Other AdminSite views have admin_site attributes.

The base implementation uses modelform_factory() to sub > form , modified by attributes such as fields and exclude . So, for example, if you wanted to offer additional fields to superusers, you could swap in a different base form like so:

You may also simply return a custom ModelForm class directly.

ModelAdmin. get_formsets_with_inlines (request, obj=None) [source] ¶

Yields ( FormSet , InlineModelAdmin ) pairs for use in admin add and change views.

For example if you wanted to display a particular inline only in the change view, you could overr > get_formsets_with_inlines as follows:

The formfield_for_foreignkey method on a ModelAdmin allows you to override the default formfield for a foreign keys field. For example, to return a subset of objects for this foreign key field based on the user:

This uses the HttpRequest instance to filter the Car foreign key field to only display the cars owned by the User instance.

ModelAdmin. formfield_for_manytomany (db_field, request, **kwargs

Like the formfield_for_foreignkey method, the formfield_for_manytomany method can be overr > Car foreign key field to only display the cars owned by the User :

Like the formfield_for_foreignkey and formfield_for_manytomany methods, the formfield_for_choice_field method can be overridden to change the default formfield for a field that has declared choices. For example, if the choices available to a superuser should be different than those available to regular staff, you could proceed as follows:

Returns the Changelist > django.contrib.admin.views.main.ChangeList is used. By inheriting this class you can change the behavior of the listing.

ModelAdmin. get_changelist_form (request, **kwargs) [source] ¶

Returns a ModelForm > Formset on the changelist page. To use a custom form, for example:


Returns a ModelFormSet > list_editable is used. To use a custom formset, for example:

The objects in the changelist page can be filtered with lookups from the URL’s query string. This is how list_filter works, for example. The lookups are similar to what’s used in QuerySet.filter() (e.g. user__email=user@example.com ). Since the lookups in the query string can be manipulated by the user, they must be sanitized to prevent unauthorized data exposure.

By default, lookup_allowed() allows access to a model’s local fields, field paths used in list_filter (but not paths from get_list_filter() ), and lookups required for limit_choices_to to function correctly in raw_id_fields .

ModelAdmin. has_view_permission (request, obj=None

Should return True if viewing obj is permitted, False otherwise. If obj is None , should return True or False to indicate whether viewing of objects of this type is permitted in general (e.g., False will be interpreted as meaning that the current user is not permitted to view any object of this type).

The default implementation returns True if the user has either the “change” or “view” permission.

ModelAdmin. has_add_permission (request

Should return True if adding an object is permitted, False otherwise.

ModelAdmin. has_change_permission (request, obj=None

Should return True if editing obj is permitted, False otherwise. If obj is None , should return True or False to indicate whether editing of objects of this type is permitted in general (e.g., False will be interpreted as meaning that the current user is not permitted to edit any object of this type).

ModelAdmin. has_delete_permission (request, obj=None

Should return True if deleting obj is permitted, False otherwise. If obj is None , should return True or False to indicate whether deleting objects of this type is permitted in general (e.g., False will be interpreted as meaning that the current user is not permitted to delete any object of this type).

ModelAdmin. has_module_permission (request

ModelAdmin. get_queryset (request

The get_queryset method on a ModelAdmin returns a QuerySet of all model instances that can be edited by the admin site. One use case for overriding this method is to show objects owned by the logged-in user:

Sends a message to the user using the django.contrib.messages backend. See the custom ModelAdmin example .

Keyword arguments allow you to change the message level, add extra CSS tags, or fail silently if the contrib.messages framework is not installed. These keyword arguments match those for django.contrib.messages.add_message() , see that function’s documentation for more details. One difference is that the level may be passed as a string label in addition to integer/constant.

ModelAdmin. get_paginator (request, queryset, per_page, orphans=0, allow_empty_first_page=True) [source] ¶

Returns an instance of the paginator to use for this view. By default, instantiates an instance of paginator .

ModelAdmin. response_add (request, obj, post_url_continue=None) [source] ¶

Determines the HttpResponse for the add_view() stage.

response_add is called after the admin form is submitted and just after the object and all the related instances have been created and saved. You can override it to change the default behavior after the object has been created.

ModelAdmin. response_change (request, obj) [source] ¶

Determines the HttpResponse for the change_view() stage.

response_change is called after the admin form is submitted and just after the object and all the related instances have been saved. You can override it to change the default behavior after the object has been changed.

Determines the HttpResponse for the delete_view() stage.

response_delete is called after the object has been deleted. You can override it to change the default behavior after the object has been deleted.

obj_display is a string with the name of the deleted object.

obj_id is the serialized identifier used to retrieve the object to be deleted.

ModelAdmin. get_changeform_initial_data (request) [source] ¶

A hook for the initial data on admin change forms. By default, fields are given initial values from GET parameters. For instance, ?name=initial_value will set the name field’s initial value to be initial_value .

This method should return a dictionary in the form <'fieldname': 'fieldval'>:

A hook for customizing the deletion process of the delete_view() and the “delete selected” action .

The objs argument is a homogeneous iterable of objects (a QuerySet or a list of model instances) to be deleted, and request is the HttpRequest .

This method must return a 4-tuple of (deleted_objects, model_count, perms_needed, protected) .

deleted_objects is a list of strings representing all the objects that will be deleted. If there are any related objects to be deleted, the list is nested and includes those related objects. The list is formatted in the template using the unordered_list filter.

model_count is a dictionary mapping each model’s verbose_name_plural to the number of objects that will be deleted.

perms_needed is a set of verbose_name s of the models that the user doesn’t have permission to delete.

protected is a list of strings representing of all the protected related objects that can’t be deleted. The list is displayed in the template.

Other methods¶

Django view for the model instance addition page. See note below.

Django view for the model instance editing page. See note below.

ModelAdmin. changelist_view (request, extra_context=None) [source] ¶

Django view for the model instances change list/actions page. See note below.

Django view for the model instance(s) deletion confirmation page. See note below.

Django view for the page that shows the modification history for a given model instance.

Unlike the hook-type ModelAdmin methods detailed in the previous section, these five methods are in reality designed to be invoked as Django views from the admin application URL dispatching handler to render the pages that deal with model instances CRUD operations. As a result, completely overriding these methods will significantly change the behavior of the admin application.

One common reason for overriding these methods is to augment the context data that is provided to the template that renders the view. In the following example, the change view is overridden so that the rendered template is provided some extra mapping data that would not otherwise be available:

These views return TemplateResponse instances which allow you to easily customize the response data before rendering. For more details, see the TemplateResponse documentation .

ModelAdmin asset definitions¶

There are times where you would like add a bit of CSS and/or JavaScript to the add/change views. This can be accomplished by using a Media inner > ModelAdmin :

The staticfiles app prepends STATIC_URL (or MEDIA_URL if STATIC_URL is None ) to any asset paths. The same rules apply as regular asset definitions on forms .

jQuery¶

Django admin JavaScript makes use of the jQuery library.

To avo > django.jQuery . If you want to use jQuery in your own admin JavaScript without including a second copy, you can use the django.jQuery object on changelist and add/edit views.

jQuery was upgraded from 2.2.3 to 3.3.1.

The ModelAdmin > ModelAdmin ’s list of media resources unless you have a specific need. For example, if you require the jQuery library to be in the global namespace (for example when using third-party jQuery plugins) or if you need a newer version of jQuery, you will have to include your own copy.

Django prov > jquery.js and jquery.min.js respectively.

ModelAdmin and InlineModelAdmin have a media property that returns a list of Media objects which store paths to the JavaScript files for the forms and/or formsets. If DEBUG is True it will return the uncompressed versions of the various JavaScript files, including jquery.js ; if not, it will return the ‘minified’ versions.

Adding custom validation to the admin¶

Adding custom val > django.forms , and the ModelAdmin class gives you the ability define your own form:

MyArticleAdminForm can be defined anywhere as long as you import where needed. Now within your form you can add your own custom validation for any field:

It is important you use a ModelForm here otherwise things can break. See the forms documentation on custom validation and, more specifically, the model form validation notes for more information.

InlineModelAdmin objects¶

The admin interface has the ability to edit models on the same page as a parent model. These are called inlines. Suppose you have these two models:

You can edit the books authored by an author on the author page. You add inlines to a model by specifying them in a ModelAdmin.inlines :

Django prov > InlineModelAdmin and they are:

The difference between these two is merely the template used to render them.

InlineModelAdmin options¶

InlineModelAdmin shares many of the same features as ModelAdmin , and adds some of its own (the shared features are actually defined in the BaseModelAdmin superclass). The shared features are:

The InlineModelAdmin class adds or customizes:

The model which the inline is using. This is required.

The name of the foreign key on the model. In most cases this will be dealt with automatically, but fk_name must be specified explicitly if there are more than one foreign key to the same parent model.

This defaults to BaseInlineFormSet . Using your own formset can give you many possibilities of customization. Inlines are built around model formsets .

The value for form defaults to ModelForm . This is what is passed through to inlineformset_factory() when creating the formset for this inline.

A list or tuple containing extra CSS > None . As with > fieldsets , inlines with a collapse class will be initially collapsed and their header will have a small “show” link.

This controls the number of extra forms the formset will display in addition to the initial forms. See the formsets documentation for more information.

For users with JavaScript-enabled browsers, an “Add another” link is prov > extra argument.

The dynamic link will not appear if the number of currently displayed forms exceeds max_num , or if the user does not have JavaScript enabled.

InlineModelAdmin.get_extra() also allows you to customize the number of extra forms.

This controls the maximum number of forms to show in the inline. This doesn’t directly correlate to the number of objects, but can if the value is small enough. See Limiting the number of editable objects for more information.

InlineModelAdmin.get_max_num() also allows you to customize the maximum number of extra forms.

This controls the minimum number of forms to show in the inline. See modelformset_factory() for more information.

InlineModelAdmin.get_min_num() also allows you to customize the minimum number of displayed forms.

By default, Django’s admin uses a select-box interface ( ) for fields that are ForeignKey . Sometimes you don’t want to incur the overhead of having to select all the related instances to display in the drop-down.

raw_id_fields is a list of fields you would like to change into an Input w > ForeignKey or ManyToManyField :

The template used to render the inline on the page.

An overr > verbose_name found in the model’s inner Meta class.

An overr > verbose_name_plural found in the model’s inner Meta class.

Specifies whether or not inline objects can be deleted in the inline. Defaults to True .

Specifies whether or not inline objects that can be changed in the admin have a link to the change form. Defaults to False .

InlineModelAdmin. get_formset (request, obj=None, **kwargs

Returns a BaseInlineFormSet > obj is the parent object being edited or None when adding a new parent. See the example for ModelAdmin.get_formsets_with_inlines .

InlineModelAdmin. get_extra (request, obj=None, **kwargs

Returns the number of extra inline forms to use. By default, returns the InlineModelAdmin.extra attribute.

Returns the maximum number of extra inline forms to use. By default, returns the InlineModelAdmin.max_num attribute.

Returns the minimum number of inline forms to use. By default, returns the InlineModelAdmin.min_num attribute.

InlineModelAdmin. has_add_permission (request, obj

Should return True if adding an inline object is permitted, False otherwise. obj is the parent object being edited or None when adding a new parent.

The obj argument was added. During the deprecation period, it may also be None if third-party calls to has_add_permission() don’t provide it.

Should return True if editing an inline object is permitted, False otherwise. obj is the parent object being edited.

InlineModelAdmin. has_delete_permission (request, obj=None

Should return True if deleting an inline object is permitted, False otherwise. obj is the parent object being edited.

The obj argument passed to InlineModelAdmin methods is the parent object being edited or None when adding a new parent.

Working with a model with two or more foreign keys to the same parent model¶

It is sometimes possible to have more than one foreign key to the same model. Take this model for instance:


If you wanted to display an inline on the Person admin add/change pages you need to explicitly define the foreign key since it is unable to do so automatically:

Working with many-to-many models¶

By default, admin w > ManyToManyField . Depending on your ModelAdmin definition, each many-to-many field in your model will be represented by a standard HTML multiple> , a horizontal or vertical filter, or a raw_id_admin widget. However, it is also possible to replace these widgets with inlines.

Suppose we have the following models:

If you want to display many-to-many relations using an inline, you can do so by defining an InlineModelAdmin object for the relationship:

There are two features worth noting in this example.

Firstly — the MembershipInline > Group.members.through . The through attribute is a reference to the model that manages the many-to-many relation. This model is automatically created by Django when you define a many-to-many field.

Secondly, the GroupAdmin must manually exclude the members field. Django displays an admin w > Group ). If you want to use an inline model to represent the many-to-many relationship, you must tell Django’s admin to not display this widget — otherwise you will end up with two widgets on your admin page for managing the relation.

Note that when using this technique the m2m_changed signals aren’t triggered. This is because as far as the admin is concerned, through is just a model with two foreign key fields rather than a many-to-many relation.

In all other respects, the InlineModelAdmin is exactly the same as any other. You can customize the appearance using any of the normal ModelAdmin properties.

Working with many-to-many intermediary models¶

When you specify an intermediary model using the through argument to a ManyToManyField , the admin will not display a widget by default. This is because each instance of that intermediary model requires more information than could be displayed in a single widget, and the layout required for multiple widgets will vary depending on the intermediate model.

However, we still want to be able to edit that information inline. Fortunately, this is easy to do with inline admin models. Suppose we have the following models:

The first step in displaying this intermediate model in the admin is to define an inline > Membership model:

This simple example uses the default InlineModelAdmin values for the Membership model, and limits the extra add forms to one. This could be customized using any of the options available to InlineModelAdmin classes.

Now create admin views for the Person and Group models:

Finally, register your Person and Group models with the admin site:

Now your admin site is set up to edit Membership objects inline from either the Person or the Group detail pages.

Using generic relations as an inline¶

It is possible to use an inline with generically related objects. Let’s say you have the following models:

If you want to allow editing and creating an Image instance on the Product , add/change views you can use GenericTabularInline or GenericStackedInline (both sub > GenericInlineModelAdmin ) prov > admin . They implement tabular and stacked visual layouts for the forms representing the inline objects, respectively, just like their non-generic counterparts. They behave just like any other inline. In your admin.py for this example app:

See the contenttypes documentation for more specific information.

Overriding admin templates¶

It is relatively easy to override many of the templates which the admin module uses to generate the various pages of an admin site. You can even override a few of these templates for a specific app, or a specific model.

Set up your projects admin template directories¶

The admin template files are located in the contrib/admin/templates/admin directory.

In order to overr > admin directory in your project’s templates directory. This can be any of the directories you specified in the DIRS option of the DjangoTemplates backend in the TEMPLATES setting. If you have customized the ‘loaders’ option, be sure ‘django.template.loaders.filesystem.Loader’ appears before ‘django.template.loaders.app_directories.Loader’ so that your custom templates will be found by the template loading system before those that are included with django.contrib.admin .

Within this admin directory, create sub-directories named after your app. Within these app subdirectories create sub-directories named after your models. Note, that the admin app will lowercase the model name when looking for the directory, so make sure you name the directory in all lowercase if you are going to run your app on a case-sensitive filesystem.

To overr > django/contrib/admin/templates/admin directory, and save it to one of the directories you just created.

For example, if we wanted to add a tool to the change list view for all the models in an app named my_app , we would copy contrib/admin/templates/admin/change_list.html to the templates/admin/my_app/ directory of our project, and make any necessary changes.

If we wanted to add a tool to the change list view for only a specific model named ‘Page’, we would copy that same file to the templates/admin/my_app/page directory of our project.

Overriding vs. replacing an admin template¶

Because of the modular design of the admin templates, it is usually neither necessary nor advisable to replace an entire template. It is almost always better to override only the section of the template which you need to change.

To continue the example above, we want to add a new link next to the History tool for the Page model. After looking at change_form.html we determine that we only need to overr > object-tools-items block. Therefore here is our new change_form.html :

And that’s it! If we placed this file in the templates/admin/my_app directory, our link would appear on the change form for all models within my_app.

Templates which may be overridden per app or model¶

Not every template in contrib/admin/templates/admin may be overridden per app or per model. The following can:

  • actions.html
  • app_index.html
  • change_form.html
  • change_form_object_tools.html
  • change_list.html
  • change_list_object_tools.html
  • change_list_results.html
  • date_hierarchy.html
  • delete_confirmation.html
  • object_history.html
  • pagination.html
  • popup_response.html
  • prepopulated_fields_js.html
  • search_form.html
  • submit_line.html

The ability to overr > actions.html , change_form_object_tools.html , change_list_object_tools.html , change_list_results.html , date_hierarchy.html , pagination.html , prepopulated_fields_js.html , search_form.html , and submit_line.html templates was added.

For those templates that cannot be overr > templates/admin directory. This is particularly useful to create custom 404 and 500 pages.

Some of the admin templates, such as change_list_results.html are used to render custom inclusion tags. These may be overridden, but in such cases you are probably better off creating your own version of the tag in question and giving it a different name. That way you can use it selectively.

Root and login templates¶

If you wish to change the index, login or logout templates, you are better off creating your own AdminSite instance (see below), and changing the AdminSite.index_template , AdminSite.login_template or AdminSite.logout_template properties.

AdminSite objects¶

A Django administrative site is represented by an instance of django.contrib.admin.sites.AdminSite ; by default, an instance of this > django.contrib.admin.site and you can register your models and ModelAdmin instances with it.

If you want to customize the default admin site, you can override it .

AdminSite attributes¶

The text to put at the top of each admin page, as an

(a string). By default, this is “Django administration”.

The text to put at the end of each admin page’s (a string). By default, this is “Django site admin”.

The URL for the “View site” link at the top of each admin page. By default, site_url is / . Set it to None to remove the link.

For sites running on a subpath, the each_context() method checks if the current request has request.META[‘SCRIPT_NAME’] set and uses that value if site_url isn’t set to something other than / .

The text to put at the top of the admin index page (a string). By default, this is “Site administration”.

Path to a custom template that will be used by the admin site main index view.

Path to a custom template that will be used by the admin site app index view.

The string to use for displaying empty values in the admin site’s change list. Defaults to a dash. The value can also be overr > ModelAdmin basis and on a custom field within a ModelAdmin by setting an empty_value_display attribute on the field. See ModelAdmin.empty_value_display for examples.

Path to a custom template that will be used by the admin site login view.

Sub > AuthenticationForm that will be used by the admin site login view.

Path to a custom template that will be used by the admin site logout view.

Path to a custom template that will be used by the admin site password change view.

Path to a custom template that will be used by the admin site password change done view.

AdminSite methods¶

Returns a dictionary of variables to put in the template context for every page in the admin site.

Includes the following variables and values by default:

available_apps : a list of applications from the application registry available for the current user. Each entry in the list is a dict representing an application with the following keys:

  • app_label : the application label
  • app_url : the URL of the application index in the admin
  • has_module_perms : a boolean indicating if displaying and accessing of the module’s index page is permitted for the current user
  • models : a list of the models available in the application

Each model is a dict with the following keys:

  • object_name : > name : plural name of the model
  • perms : a dict tracking add , change , delete , and view permissions
  • admin_url : admin changelist URL for the model
  • add_url : admin URL to add a new model instance

AdminSite. has_permission (request) [source]¶

Returns True if the user for the given HttpRequest has permission to view at least one page in the admin site. Defaults to requiring both User.is_active and User.is_staff to be True .

Registers the given model > admin_class . admin_class defaults to ModelAdmin (the default admin options). If keyword arguments are given – e.g. list_display – they’ll be applied as options to the admin class.

Raises ImproperlyConfigured if a model is abstract. and django.contrib.admin.sites.AlreadyRegistered if a model is already registered.

Hooking AdminSite instances into your URLconf¶

The last step in setting up the Django admin is to hook your AdminSite instance into your URLconf. Do this by pointing a given URL at the AdminSite.urls method. It is not necessary to use include() .

In this example, we register the default AdminSite instance django.contrib.admin.site at the URL /admin/

Customizing the AdminSite class¶

If you’d like to set up your own admin site with custom behavior, you’re free to sub > AdminSite and overr > AdminSite sub > ModelAdmin sub > myproject/urls.py to reference your AdminSite subclass.

Note that you may not want autodiscovery of admin modules when using your own AdminSite instance since you will likely be importing all the per-app admin modules in your myproject.admin module. This means you need to put ‘django.contrib.admin.apps.SimpleAdminConfig’ instead of ‘django.contrib.admin’ in your INSTALLED_APPS setting.

Overr > New in Django 2.1:

You can overr > django.contrib.admin.site by setting the default_site attribute of a custom AppConfig to the dotted import path of either a AdminSite subclass or a callable that returns a site instance.

Multiple admin sites in the same URLconf¶

It’s easy to create multiple instances of the admin site on the same Django-powered website. Just create multiple instances of AdminSite and root each one at a different URL.

In this example, the URLs /basic-admin/ and /advanced-admin/ feature separate versions of the admin site – using the AdminSite instances myproject.admin.basic_site and myproject.admin.advanced_site , respectively:

AdminSite instances take a single argument to their constructor, their name, which can be anything you like. This argument becomes the prefix to the URL names for the purposes of reversing them . This is only necessary if you are using more than one AdminSite .

Adding views to admin sites¶

Just like ModelAdmin , AdminSite prov > get_urls() method that can be overr > get_urls() method to include a pattern for your new view.

Any view you render that uses the admin templates, or extends the base admin template, should set request.current_app before rendering the template. It should be set to either self.name if your view is on an AdminSite or self.admin_site.name if your view is on a ModelAdmin .

Adding a password reset feature¶

You can add a password reset feature to the admin site by adding a few lines to your URLconf. Specifically, add these four patterns:

(This assumes you’ve added the admin at admin/ and requires that you put the URLs starting with ^admin/ before the line that includes the admin app itself).

The presence of the admin_password_reset named URL will cause a “forgotten your password?” link to appear on the default admin log-in page under the password box.

LogEntry objects¶

The LogEntry class tracks additions, changes, and deletions of objects done through the admin interface.

LogEntry attributes¶

The date and time of the action.

The user (an AUTH_USER_MODEL instance) who performed the action.

The ContentType of the modified object.

The textual representation of the modified object’s primary key.

The object`s repr() after the modification.

The type of action logged: ADDITION , CHANGE , DELETION .

For example, to get a list of all additions done through the admin:


The detailed description of the modification. In the case of an edit, for example, the message contains a list of the edited fields. The Django admin site formats this content as a JSON structure, so that get_change_message() can recompose a message translated in the current user language. Custom code might set this as a plain string though. You are advised to use the get_change_message() method to retrieve this value instead of accessing it directly.

LogEntry methods¶

A shortcut that returns the referenced object.

Formats and translates change_message into the current user language. Messages created before Django 1.10 will always be displayed in the language in which they were logged.

Reversing admin URLs¶

The AdminSite provides the following named URL patterns:

Page URL name Parameters
Index index
Login login
Logout logout
Password change password_change
Password change done password_change_done
i18n JavaScript jsi18n
Application index page app_list app_label
Redirect to object’s page view_on_site content_type_id , object_id

Each ModelAdmin instance provides an additional set of named URLs:

Page URL name Parameters
Changelist << app_label >>_<< model_name >>_changelist
Add << app_label >>_<< model_name >>_add
History << app_label >>_<< model_name >>_history object_id
Delete << app_label >>_<< model_name >>_delete object_id
Change << app_label >>_<< model_name >>_change object_id

The UserAdmin provides a named URL:

Page URL name Parameters
Password change auth_user_password_change user_id

These named URLs are registered with the application namespace admin , and with an instance namespace corresponding to the name of the Site instance.

So — if you wanted to get a reference to the Change view for a particular Choice object (from the polls application) in the default admin, you would call:

This will find the first registered instance of the admin application (whatever the instance name), and resolve to the view for changing poll.Choice instances in that instance.

If you want to find a URL in a specific admin instance, prov > current_app hint to the reverse call. For example, if you specifically wanted the admin view from the admin instance named custom , you would need to call:

For more details, see the documentation on reversing namespaced URLs .

To allow easier reversing of the admin urls in templates, Django prov > admin_urlname filter which takes an action as argument:

The action in the examples above match the last part of the URL names for ModelAdmin instances described above. The opts variable can be any object which has an app_label and model_name attributes and is usually supplied by the admin views for the current model.

The staff_member_required decorator¶

This decorator is used on the admin views that require authorization. A view decorated with this function will having the following behavior:

Python Django CMS — FeinCMS

Python CMS

Не буду углубляться в терминологию, думаю что те кто зашел на мой блог и так прекрасно осведомлены о том что такое CMS. Для всех веб разработчиков всегда существует дилема выбора готовой CMS или написания своей собственной. Поскольку я не занимаюсь созданием сайтов в промышленных масштабах, то пытаюсь найти нечто готовое, изучить и по-возможности переиспользовать. В моем подходе есть недостатки, так как редко получается найти на 100% подходящее решение и зачастую кода больше чем необходимо. Но этот подход, с чем невозможно поспорить, увеличивает скорость разработки и улучшает кругозор, потому что исследуется чужой код. В основном, в работе я использую Django Framework. Но появилась необходимость в системе управления статическими страницами, для которой встроенное приложение django static pages уже недостаточно. Держать Django приложение для простого 10 страничного сайта, это неразумно, хоть я в итоге и делаю теперь так, в угоде других приоритетов, несколько сайтов на одной CMS, правильный шаблонизатор с наследованием. Но изначально хотелось что-нибудь поменьше, а также более юзерфрэндли для конечных пользователей. Так чтобы пользователь без лишних вопросов мог добавить страничку, отредактировать ее в tinymce или добавить видео из youtube лего и бысто. В общем набор как всегда взаимоисключающих требований. Но первое и самое важное для меня — это обязательно язык программирования Python. И в данном сегменте я нашел более 10 хороших вариантов, для изучения:

  1. Django CMS — основан на django
  2. PyLucid — основан на django
  3. Mezzanine — основан на django
  4. Pinax — основан на django
  5. Merengue — основан на django
  6. FeinCMS — основан на django
  7. DjangoLFC — быстрая CMS на django
  8. Plone — большой Zope основанный
  9. Kotti — основано на Pyramid
  10. Quokka project — основан на Flask (база данных MongoDB)
  11. Skeletonz
  12. NiVE
  13. ikaaro
  14. wagtail
  15. bottle — вообще micro cms

Сразу выбрал DjangoCMS, но она меня не впечатлила, осталась такой же как и была 10 лет назад и как всегда с ней установилось 100500 пакетов, дизайн меня не впечатлил, сложно обучать человека работать с админкой, Kotti — абсолютно другой подход и совершенно не известная для меня технология (обязательно к этому еще вернусь), Quokka пожалуй одна из лучших систем на сегодняшний день, очень удачная для пользователя, не перегруженная, современная, лишенная недостатков концепции фундамента, в виде больших фреймворков. Но есть одно но — это база данных MongoDB, если бы была база данных PostgreSQL то я бы выбрал её. После изучения каждого из вариантов, времени осталось мало и я решил — выберу что-нибудь более ли менее стабильное, то что я знаю, не перегруженное, и поскольку выяснилось, что Django cms приложение — Django cms приложению рознь мой выбор пал на FeinCMS.

О ней я сегодня и напишу.

FeinCMS

CMS написанная на Python, основана на Django, а в Django есть коровья сила — это значит, что при установке CMS у нас будут все бесчисленные возможности фреймворка Django. Библиотека содержит множество готовых решений для повседневных задач веб разработчика, позволяет быстро стартовать, а язык разработки гарантирует вам хорошую поддерживаемость кода. FeinCMS — это больше, чем система управления контентом (не только благодаря Django). Например, FeinCMS позволяет определить свои типы содержимого (Content Type), таким образом CMS представляется уже системой разработки веб приложений. В админке же есть все необходимое прямо из коробки для управления пользовательским контентом.

Важно! Принципы установки FeinCMS теже, что и у любого другого Django приложения. Это руководство будет также полезно для начинающих знакомиться с фреймворком Django.

К плюсам FeinCMS можно отнести также наличие, отнюдь не исчерпывающей, но официальной документации на readthedocs.org

Подготовка к установке FeinCMS

Необходимо обновить операционную систему. Все команды выполеняются под привелегированной учетной записью (от root)

Далее установим необходимые библиотеки необходимые для работы Python и для установки его модулей

Установка FeinCMS

Настроим виртуальное окружении, чтобы безопасно для системы установить FeinCMS со всеми зависимостями.

Активируем виртуальное окружение

На сегодня 5 апреля 2015 у FeinCMS существуют проблемы с django 1.8, поэтому перед установкой cms следует установить django 1.7, остальные зависимости подтянутся вместе с FeinCMS.

Установим модуль для работы с базой данных в моем случае это PostgreSQL (для MySQL mysql-python )

Подготовка FeinCMS

Для запуска FeinCMS необходимо создать Django проект, в настройках которого прописать приложение feincms.

Необходимо создать пользовательское приложение cms

Изменим файл настроек Django в соостветствии с приложениями

Внесем изменения в кортеж INSTALLED_APPS , добавим feincms приложения и cms :

Необходимо изменить настройку базы данных

Для запуска необходимо удалить или закомментировать строчку security в кортеже MIDDLEWARE_CLASSES

Подправим директорию поиска тэмплейтов:

Для работы нужно urls.py привести к виду

Создание базы данных

Для работы FeinCMS требуются модели. Это отличие этой CMS от других. Поэтому прежде чем создать базу данных необходимо создать модели.

Полное описание Page модуля FeinCMS в документации

Инициализируем базу данных

Создание темплейта

Нуобходима директория для хранения темплейтов

Отредактируем темплейт модели, которую мы создали выше

Тестируем приложение

Запустим тестовый Django сервер

Заходим в Django админку и создаем страницы на основе нашей модели

Спасибо за внимание! Статья обязательно будет обновляться в соответствии с вашими комментариями. Да, еще, ;) если статья была вам полезна, щелкните по рекламе.

Подключение интерфейса администратора Django

В предыдущих мануалах этой серии Django вы узнали, как запустить приложение Django, связать его с MySQL и создать модели баз данных Posts и Comments.

Читайте также:

Данный мануал научит вас подключать интерфейс администратора Django для управления блогом. Интерфейс администратора Django предварительно поставляется вместе с пользовательским интерфейсом, который предназначен для управления контентом веб-сайта.

Стоит отметить: официальная документация Django указывает, что автоматически созданный интерфейс администратора Django идеально подходит для внутреннего использования организации, однако создавать веб-приложение на его основе крайне не рекомендуется. Чтобы сделать интерфейс более ориентированным на процесс, лучше написать собственные виды для администраторской части.

1: Включение Django Admin

Чтобы включить Django Admin, нужно добавить его в список INSTALLED_APPS в файле settings.py.

Перейдите в каталог:

Теперь откройте settings.py:

Если django.contrib.admin еще нет в списке INSTALLED_APPS, добавьте в список эту строку. Список должен выглядеть так:

.
# Application definition
INSTALLED_APPS = [
‘blogsite’,
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
]
.

Сохраните и закройте файл.

Затем откройте файл urls.py:

Этот файл должен выглядеть так:

.
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r’^admin/’, admin.site.urls),
]

Как видите, значение r^admin/ передается аргументу url. Так Python выполняет регулярные выражения.

Регулярные выражения – это способ поиска или сопоставления строковых шаблонов. Python использует r, чтобы интерпретировать следующий текст после символа каретки (^) как необработанную строку. Другими словами, специальные символы, такие как слеш (/), будут интерпретироваться так, как они есть, что полезно в случае с urls.

Теперь, когда веб-проект Django имеет соответствующий код в файлах settings.py и urls.py, у приложения есть доступ к моделям и пользовательскому интерфейсу администратора.

2: Проверка установки Django Admin

Теперь нужно мигрировать модели в БД, чтобы она смогла обрабатывать новые модели Admin.

Откройте каталог, в котором хранится файл manage.py.

Запустите команду migrate, чтобы обновить модели (это нужно делать всякий раз, когда вы вносите какие-либо изменения в модели).

python3 manage.py migrate

Команда должна вернуть следующий вывод, потому что модель admin уже была добавлена, как вы видели при навигации по разделам INSTALLED_APPS файла settings.py.

Operations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
No migrations to apply.

Теперь можно запустить сервер с помощью команды:

python3 manage.py runserver your-server-ip:8000

Затем можно открыть URL панели администратора в браузере:

На экране появится форма входа.

Если это так – вы успешно включили интерфейс администратора.

Однако пока что у вас нет аккаунта администратора. Создайте такой аккаунт, чтобы войти в интерфейс.

3: Создание учетной записи администратора

В браузере открывается страница входа в интерфейс, но пока что у вас нет учетных данных. Создать эти данные совсем не сложно.

Django предоставляет простой способ создания учетной записи суперпользователя. Для этого нужно запустить файл manage.py.

python3 manage.py createsuperuser

После этого будет запрошено имя пользователя, электронная почта и пароль. В данном руководстве используются условные данные admin_user, 8host@example.com и admin123. Укажите свои учетные данные, используйте сложный пароль.

Username (leave blank to use ‘root’): admin_user
Email address: 8host@example.com

Затем программа попросит дважды ввести пароль администратора в поле Password. При этом в поле не будут отображаться никакие символы – это делается в целях безопасности. Введя пароль, нажмите enter.

Password:
Password (again):

На данный момент у вас есть учетная запись администратора admin_user с паролем admin123.

Давайте попробуем войти в интерфейс администратора.

Откройте в браузере страницу:

Затем войдите в интерфейс, указав имя и пароль, которые вы только что создали. Вы получите доступ к странице Site administration.

Теперь нужно подключить блог к панели администратора.

4: Создание URL-шаблонов для моделей Post и Comment

Как видите, интерфейс администратора до сих пор не видит ваше приложение. Чтобы изменить это, нужно добавить и зарегистрировать блог с соответствующими моделями Post и Comment.

Создайте пустой файл urls.py в каталоге blogsite:


В этот файл можно вставить шаблон URL для блога, чтобы иметь возможность получить доступ к нему через интерфейс администратора.

Перейдите к каталогу, в котором хранится файл urls.py.

Добавьте в него такой код:

from django.conf.urls import url
from . import views
urlpatterns = [
url(r’^$’, views.posts, name=’posts’),
url(r’^$’, views.comments, name=’comments’)
]

Это выражения шаблонов URL, с помощью которых приложение может получить доступ к представлениям (views) для Posts и Comments (пока что их нет, но об этом речь пойдет в одном из мануалов данной серии).

5: Подключение блога к Django Admin

Подключив блог к интерфейсу администратора, вы сможете увидеть ссылки на Posts и Comments в панели. Как вы уже видели, на данный момент панель отображает только ссылки на Groups и Users.

Зарегистрируйте модели Posts и Comments в файле admin в каталоге blogsite.

Затем создайте файл admin.py:

Добавьте в файл следующие строки:

from django.contrib import admin
from blogsite.models import Post
from blogsite.models import Comment
admin.site.register(Post)
admin.site.register(Comment)

Сохраните и закройте файл.

Теперь модели Post и Comment зарегистрированы в панели администратора. Это позволит интерфейсу администратора выбирать эти модели и показывать их пользователю, который имеет доступ к панели.

6: Проверка настроек

Теперь, когда вы добавили соответствующий код Python, запустите сервер. Откройте страницу:

и войдите в аккаунт администратора, используя свои учетные данные.

На странице Site authorization вы увидите, что кроме моделей Authorization and authentication появится группа Blogsite, в которой будут ваши модели блога.

Заключение

Вы успешно подключили панель администратора к блогу.

Интерфейс администратора Django позволяет создавать сообщения и отслеживать комментарии в блоге.

В следующем мануале этой серии вы научитесь создавать представления для приложения.

Администрирование Django

Чтобы добавлять, редактировать и удалять записи, для которых мы только что создали модель, мы используем панель управления администратора Django.

Давай откроем файл blog/admin.py и заменим его содержимое на:

Как ты можешь заметить, мы импортировали (включили) модель 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 , чтобы продолжить. Результат должен выглядеть следующим образом (имя пользователя и почта, соответственно, будут твоими):

Вернись в браузер и войди в систему при помощи имени пользователя и пароля, которые ты только что выбрала. Ты должна попасть в панель управления Django.

Перейди к разделу Posts и немного поэкспериментируй с ним. Добавь пять или шесть постов. Не беспокойся о содержании — можешь просто скопировать и вставить текст из этого учебника, чтобы сэкономить время :)

Убедись, что выбрала для двух или трёх записей (но не больше) дату публикации. Это пригодится позднее.

Если ты хочешь узнать больше об администрировании Django, то ознакомься с этим разделом официальной документации: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/.

Сейчас, вероятно, подходящий момент, чтобы порадовать себя кружечкой кофе (или чая), а также съесть чего-нибудь для восполнения энергии. Ты только что создала свою первую модель Django и заслужила перерыв!

Создание сайта на Wagtail (CMS на Django)

В мире Python концепт CMS, не похож с тем что вы возможно встречали в PHP (WordPress). Разобраться в PHP с готовым CMS гораздо легче чем в Python. На данный момент существуют несколько CMS которые используют фреймворк Django, самые популярные из них это django-cms и Wagtail. В данной статье мы будем выполнять первые шаги к собственному сайту на Python используя Wagtail.

Настройка сервера (VPS)

Обычный хостинг для такого проекта будет недостаточно. Если для блога на PHP достаточно заказать обычный хостинг, то для веб проекта на Python мы рекомендуем полноценный VPS на операционной системе Linux от Fornex.com Мы долгое время пользуемся их услугами для нескольких наших проектов и можем рекомендовать их.

Заказ VPS

Ссылка на хостинг: Fornex

После регистрации и входа в ваш личный кабинет, у вас появится возможность заказать VPS и указать необходимые настройки. В моем случае это SSD CLOUD 1GB на операционной системе Ubuntu 18.04 LTS (это самая актуальная версия на момент написания статьи, советуем всегда выбирает самые свежие версии).

Если вы профи в Linux, то можете выбрать настройку «Без панели» при выборе панели управления, но если вы хотите иметь некий интерфейс настроек, то советуем выбрать панель управления «Vesta CP«.

Подключаемся по SSH и выполняем необходимые команды в консоли.

На VPS у меня уже был установлен Python 3.6.7 но если по каким либо причинам его у вас нет, то устанавливаем его таким образом:

Далее, устанавливаем необходимые библиотеки:

Не забываем про pip:

Все манипуляции и установки через pip выполняем исключительно в виртуальном окружении, чтобы не засорять ненужными библиотеками главное окружение. В папке /home создаем новую папку /home/web

Находясь в папке /home/web мы создадим виртуальное окружение для нашего приложения:

Вводная строка терминала изменилась на что-то подобное:

Установка Wagtail и его зависимостей:

Wagtail предоставляет команду start , аналогичную django-admin.py startproject . Запуск wagtail start mysite в вашем проекте создаст новую папку mysite со специальными дополнениями Wagtail, включая необходимые настройки проекта, приложение “home” с пустой домашней страницей, основными шаблонами и примером приложения “search”.

Установка проектных зависимостей

Здесь указывается, что у вас подходящая версия Django для созданного вами проекта.

Создание базы данных

Если вы не обновили настройки проекта, то у вас будет файл базы данных SQLite в папке проекта.

Создание пользователя admin:

Если все сработало, то http://127.0.0.1:8000 покажет страницу приветствия:

Вы можете перейти к административному разделу в http://127.0.0.1:8000/admin

Расширяем модель домашней страницы

Изначально, приложение “home” определяет пустую модель домашней страницы в models.py , наряду с миграцией, которая создает домашнюю страницу и указывает Wagtail использовать ее.

Измените home/models.py как указано внизу, чтобы внести поле body в модель:

body определено как RichTextField , специальное поле Wagtail. Вы можете использовать любые поля Django. content_panels определяет возможности и макет интерфейса редактирования.

Запустите manage.py makemigrations , затем python manage.py migrate , чтобы обновить базу данных с изменениями вашей модели. Вам следует вводить указанные команды каждый раз, когда вы вносите изменения в модели.

Теперь вы можете редактировать домашнюю страницу внутри раздела администратора Wagtail (переходить на Pages, Homepage и Edit), чтобы увидеть новое поле body . Введите какой-нибудь текст в поле body, и опубликуйте страницу.

Шаблон страницы теперь ждет обновления для отображения изменений, внесенных в модель. Wagtail использует обычные шаблоны Django для рендера каждого типа страницы. По умолчанию, он будет искать название шаблона, состоящего из названий приложения и модели, с разделенными нижним подчеркиванием названиями (например, HomePage внутри приложения “home” называется home/home_page.html ). Этот файл шаблона может существовать в любой распознаваемой правилами шаблонов Django локации. Условно, он помещает под папкой с шаблонами внутри приложения.

Теги шаблонов Wagtail

Wagtail предоставляет ряд тегов шаблонов и фильтров, которые можно загрузить внесением <% load wagtailcore_tags %>в начале вашего файла шаблона.

В данном руководстве мы используем фильтр richtext для экранирования и вывода содержимого RichTextField :

Обратите внимание: вам нужно будет вставлять <% load wagtailcore_tags %>в каждый шаблон, который использует теги Wagtail. Django будет выдавать ошибку TemplateSyntaxError, если теги не будут загружены.

Пример: Простой блог

С этого момента мы можем приступить к созданию блога. Чтобы сделать это, запустите python manage.py startapp blog , чтобы создать новое приложение в вашем сайте Wagtail.

Внесите новое приложение blog в INSTALLED_APPS в mysite/settings/base.py .

Главная страница блога и посты

Давайте начнем с простой страницы индекса для нашего блога. В blog/models.py :

Запустите python manage.py makemigrations и python manage.py migrate .

Так как модель называется BlogIndexPage , название шаблона по умолчанию (если мы не меняли его) будет blog/templates/blog/blog_index_page.html . Создайте этот файл со следующим содержимым:

Большая часть содержимого должна быть вам знакома, но мы объясним что делает get_children немного позже. Обратите внимание на тег pageurl , который аналогичен тегу url в Django, но принимает объект страницы Wagtail в качестве аргумента.

В админке Wagtail создайте BlogIndexPage в качестве дочернего элемента Homepage, убедитесь, что у него есть слаг “blog” во вкладке Promote и опубликуйте его. Теперь у вас должен появиться доступ к url /blog на вашем сайте (обратите внимание на то, как слаг из панели Promote определяет URL страницы).

Теперь нам нужна модель и шаблон для наших постов в блоге. В blog/models.py :

Запускаем в терминале python manage.py makemigrations и python manage.py migrate .

Создаем шаблон в blog/templates/blog/blog_page.html :

Обратите внимание на то, что мы использовали метод get_parent() для получения URL блога, частью которого является этот пост.

Теперь создаем несколько постов в блоге в качестве дочерних элементов BlogIndexPage . Убедитесь в том, что выбрали “Blog Page” при создании ваших постов.

Wagtail дает вам полный контроль над тем, какой тип содержимого может быть создан под различными родительскими типами контента. По умолчанию, любая страница может быть дочерней любого типа страницы.

Теперь у вас в распоряжении базовый рабочий блог. Перейдите по URL /blog и увидите что-нибудь вроде следующего:

Заголовки должны переводить к страницам постов, а ссылка на главную страницу должна появиться в футере каждой страницы поста.

Дочерние и родительские элементы

Большая часть работы, выполняемая в Wagtail вертится вокруг концепции иерархии структуры “дерева”, состоящего из ветвей и листьев. В данном случае, BlogIndexPage — ветвь, а экземпляры страниц блога являются листьями.

Рассмотрим blog_index_page.html изнутри:

Каждая “страница” в Wagtail может вызывать дочернюю или родительскую страницу со своей позиции в иерархии. Но почему мы должны определять post.specific.intro вместо post.intro ? Это напрямую связано с тем, как мы определили нашу модель:

Метод get_children() выдает нам список экземпляров основного класса Page . Когда нам нужно сослаться на свойства экземпляров, которые наследуются от базового класса, Wagtail предоставляет особый метод, который возвращает фактическую запись BlogPage . В то время как поле “title” присутствует в базовой модели Page , “intro” присутствует только в модели BlogPage , так что нам нужен .specific для получения доступа.

Чтобы сжать код шаблона, мы можем использовать тег Django под названием with :

Когда вы начинаете вписывать больше персонализированного когда в Wagtail, вы увидите целый набор модификаторов QuerySet , которые помогут вам ориентироваться по иерархии.

Переопределение контекста

Есть небольшие проблемы с главной страницей нашего блога:

  1. Контент в блогах (как правило) показывается в обратном хронологическом порядке;
  2. Нам нужно быть уверенными в том, что мы показываем только опубликованный контент (без черновиков).

Чтобы достичь этих целей, нам нужно сделать нечто большее, чем просто взять дочерние элементы страниц индекса в шаблоне.

Вместо этого, нам нужно будет обновить QuerySet в определении модели. Wagtail позволяет сделать это просто, при помощи переопределяемого метода get_context() . Изменение модели BlogIndexPage проходит следующим образом:

Все что мы сделали здесь, это вернули оригинальный контекст, создали персональный QuerySet , внесли его в полученный контекст, и вернули обновленный контекст обратно в представление. Вам также нужно будет немного обновить ваш шаблон blog_index_page.html . Измените следующее:

Теперь попробуйте отменить публикацию одного из ваших постов — он должен исчезнуть с главной страницы блога. Оставшиеся посты должны отсортированы начиная с самого нового.

Изображения

Давайте добавим возможность внесения галереи изображений в наши посты. Хотя мы можем просто вставлять картинки в тело текста, все же есть несколько преимуществ в настройке галереи изображений как нового выделенного типа объекта внутри базы данных.

Таким образом, у вас будет полный контроль над макетами и стилями изображений в шаблоне, вместо того, чтобы выкладывать их определенным образом в поле текста. Это также позволяет использовать изображения в различных местах, вне зависимости от текста блога. Например, в оглавлении на главной странице блога.

Добавим новую модель BlogPageGalleryImage в models.py :

Запускаем manage.py makemigrations и python manage.py migrate .

Здесь есть несколько новых концепций, давайте рассмотрим их все сразу:

Наследование от Orderable добавляет поле sort_order в модель, чтобы отслеживать порядок изображений в галерее.

ParentalKey от BlogPage отвечает за прикрепление изображений галереи в определенную страницу. ParentalKey работает аналогично ForeignKey , но также рассматривается как фундаментальная часть страницы в таких операциях, как отправка на модерацию и отслеживание истории изменений.

image является ForeignKey во встроенной модели Wagtail под названием Image , в которой хранятся изображения. Это включает выделенный тип панели ImageChooserPanel , который предоставляет всплывающий интерфейс для выбора существующего изображения или выбора нового. Таким образом, мы позволяем изображению существовать в нескольких галереях — фактически, мы создали мульти-отношение между страницами и изображениями.

Указание on_delete=models.CASCADE для внешнего ключа означает, что если изображение было удалено из системы, оно также будет удалено из галереи. (В других ситуациях, было бы разумным оставлять изображение в галерее, например если речь идет о странице “наши сотрудники”, где размещены снимки сотрудников, и одна из фотографий удалена по той или иной причине — было бы неплохо оставить это изображение в базе. В данном случае, мы меняем внешний ключ на blank=True, null=True, on_delete=models.SET_NULL .)

Наконец, внесение InlinePanel в BlogPage.content_panels делает изображения галереи доступными для интерфейса редактирования в BlogPage .

Настройте шаблон страницы блога, чтобы включить изображения:

Подключение админки

Сначала надо убедиться, что в файле settings.py в параметре INSTALLED_APPS есть следующие пункты:

И выполнить команду ниже, с помощью которй будут созданы необходимые таблицы, а также предложат ввести логин и пароль для администратора.

Если всё сделано правильно, то по URL http://example.com/admin должна открываться форма авторизации в админ панель.

Настройка модели с админкой

В любой папке приложения есть файл admin.py (например, pages/admin.py или news/admin.py). В данном файле надо добавить следующий код:

Теперь в админке можно обновлять модель (добавлять, редактировать или удалять элементы из базы данных).

Подключение админки

Сначала надо убедиться, что в файле settings.py в параметре INSTALLED_APPS есть следующие пункты:

И выполнить команду ниже, с помощью которй будут созданы необходимые таблицы, а также предложат ввести логин и пароль для администратора.

Если всё сделано правильно, то по URL http://example.com/admin должна открываться форма авторизации в админ панель.

Настройка модели с админкой

В любой папке приложения есть файл admin.py (например, pages/admin.py или news/admin.py). В данном файле надо добавить следующий код:

Теперь в админке можно обновлять модель (добавлять, редактировать или удалять элементы из базы данных).

Цукерберг рекомендует:  Node js - Помогите c nodejs
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих