Как переработать административный интерфейс Django с использованием Bootstrap

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

Если не сломано…

The default Django admin. (Source)

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

Так зачем тогда возиться?

Причины изменить внешний вид и ощущения администратора

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

  • Брендинг: нет ничего плохого в том, чтобы хотеть названия и цветов вашей компании вместо “Администрирование Django” (и, кстати, это соответствует лицензии BSD Django).
  • Гладкая интеграция между основным сайтом и административным разделом: возможно, вы захотите переключаться между функциями управления в фоновом режиме при навигации по сайту и наоборот, используя общий бар навигации.
  • Украшение: хотя административный раздел выглядит приемлемо и с версии 2 даже применяет принципы отзывчивого веб-дизайна (работает хорошо как на мобильных устройствах, так и на настольных компьютерах), многое может сделать хорошо спроектированный стиль-лист, чтобы сделать его более привлекательным.
  • Функционал обхода: также вы можете просто создать пользовательские выпадающие меню для администратора, отображая варианты, которые вы действительно используете, и скрывая из пользовательского интерфейса то, что вам не нужно, что может улучшить опыт пользователя.

A Practical Example

Для этого примера, и чтобы не повторяться, мы возобновим простую веб-приложение для публикации, которое мы начали для статьи Прототипирование веб-приложения с Django и Vue.js.

В двух словах:

  • a Django app with two models:
  • Статья с полями название, автор (связанные), содержание и слаг
  • Автор: с полями имя и слаг
  • A single view called frontend that queries all registries in both models.
  • A single template called template.
  • Реализация Vue.js с Vue Router и Vuex для реактивного масштабируемого интерфейса.

Мы не будем особо заботиться о интеграции Vue.js в этом выпуске и не будем ее здесь изменять.

Базовый Шаблон

Source

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

Source

Мы создали базовый шаблон, который связывается с Bootstrap‘с JavaScript и таблицей стилей, а также с его сопутствующими инструментами, jQuery и Popper.

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

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <title>Django and Vue.js</title>
  </head>
  <body class="bg-light">
    <div class="bg-white container">
      <h1>Prototyping a Web App with Django and Vue.js</h1>

      <!-- Content -->
    </div>

    <!-- Vue.js -->
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vue-router"></script>

    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
  </body>
</html>

Далее мы интегрируем это в админку и добавим общий навигационный бар на обе стороны — основной сайт и бэк-офис!

Интеграция Основного Шаблона UI с Админом

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

Включение Каталога для Шаблонов в Общем

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

Поэтому нам нужно отредактировать myproject/settings.py. Во-первых, найдите константу TEMPLATES и этот ключ DIRS:

'DIRS': [],

Измените этот код на следующий:

'DIRS': [os.path.join(BASE_DIR, 'templates')],

Обертка шаблона администратора (admin/base Hack)

Если мы хотим только внести косметические изменения, например, передать пользовательский стиль-лист администратору или удалить/заменить его заголовок, мы можем обойтись редактированием шаблона admin/base_site и пропустить текущий шаг. Однако, если мы хотим пойти до конца и “обернуть” раздел администратора так, будто он находится внутри нашего основного сайта, с возможностью иметь общий заголовок и футер, читайте дальше.

Нам нужно скопировать admin/base.html Django в нашу директорию шаблонов по адресу templates/admin/base.html, чтобы мы могли разместить наши обертки.

Мы отредактируем код вокруг раздела container, так что он изменится с этого:

<!-- Container -->
<div id="container">
(...)
</div>
<!-- END Container -->

на это:

{% block bodyheader %}{% endblock %}

<!-- Container -->
<div id="container">
(...)
</div>
<!-- END Container -->

{% block bodyfooter %}{% endblock %}

И это всё! Мы просто создали теги блоков bodyheader и bodyfooter, чтобы в следующем шаге вставить код, который обернет администратора.

Кодирование пользовательского шаблона администратора (admin/base_site Hack)

Тогда мы закодируем фактический шаблон в templates/admin/base_site.html (нам нужно будет создать директории на корне нашего проекта):

{% extends "admin/base_site.html" %}

{% block title %}Django with Bootstrap | Admin site{% endblock %}

{% block branding %}{% endblock %}
{% block breadcrumbs %}{% endblock %}

{% block bodyclass %}bg-light{% endblock %}

{% block extrastyle %}
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <style>
      #header, .breadcrumbs { display: none; }

      /* Проблемы Bootstrap с админом */
      * { box-sizing: unset; }
      div.module caption { caption-side: top !important; }
      .collapse { display: block !important; }
    </style>
{% endblock %}

{% block bodyheader %}
    <div class="bg-white container">

      <div class="jumbotron">
        <h1 class="display-4">Hacking the Django Admin with Bootstrap</h1>
        <p class="lead">
          The <a ref="https://docs.djangoproject.com/en/dev/ref/contrib/admin/">Django administration site</a> is great—full-featured, easy to use, secure by design, rock solid… and somewhat ugly, which can be something of a downside when you want to integrate it with the look-and-feel of the rest of the website. Let’s sort that out.
        </p>
      </div>
{% endblock %}

{% block bodyfooter %}
    </div>

    <!-- jQuery, затем Popper.js, затем Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
{% endblock %}

Разбор

Попробуем объяснить, что мы делаем здесь:

  1. Мы сообщаем движку шаблонов, что мы “расширяем” шаблон admin/base_site.html, чтобы эффективно переопределить некоторые из его определений.
  2. Мы используем блок title для настройки заголовка для страницы админки, которую просматривают.
  3. Мы очищаем содержимое блоков branding и breadcrumbs, так как нам они не особо нужны.
  4. Мы используем блок bodyclass для установки bg-light Bootstrap, как мы это делали в шаблоне frontend.
  5. Мы используем блок extrastyle для встраивания Bootstrap и некоторого CSS-кода.
    a. Хорошо, #header, .breadcrumbs { display: none; } это своего рода повторение пункта 3; но полезно знать, что вы можете отключить разделы брендинга и хлебных крошек обоими способами.
    b. При наложении Bootstrap на CSS Django в админке могут возникнуть некоторые проблемы, так что это некоторые исправления.
  6. Используйте блоки bodyheader и bodyfooter для обертывания контента админки.

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

Замечания

Мы поддерживаем два разных шаблона (главный интерфейс и административный) для выполнения по сути одного и того же представления. Несомненно, это не идеально, поскольку мы явно нарушаем одно из главных правил разработки программного обеспечения: не повторяйся (DRY).

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

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

Создание общей навигационной панели

Теперь, когда основной интерфейс и административный сайт выглядят практически одинаково, мы можем углубить наше объединение и создать общий навигационный опыт… и даже дальше, предложить некоторые административные опции прямо в главном меню!

Вот фрагмент для навигационной панели:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <ul class="navbar-nav mr-auto">
    <li class="nav-item">
      <a
        class="nav-link text-primary"
        href="/author/"
      >
        Go to Authors
      </a>
    </li>
    <li class="nav-item">
      <a
        class="nav-link text-primary"
        href="/article/"
      >
        Go to Articles
      </a>
    </li>
    {% if user.is_authenticated %}
    <li class="nav-item dropdown">
      <a
        aria-expanded="false"
        aria-haspopup="true"
        class="font-weight-bold nav-link text-primary dropdown-toggle"
        data-toggle="dropdown"
        href="#"
        role="button"
      >
        Admin
      </a>
      <div class="dropdown-menu">
        <a class="dropdown-item" href="/admin/myapp/author/">
          Manage authors
        </a>
        <a class="dropdown-item" href="/admin/myapp/article/">
          Manage articles
        </a>
      </div>
    </li>
    {% endif %}
  </ul>
</nav>

Обратите внимание на раздел dropdown-menu, который будет отвечать за представление меню администратора (подробнее см. компонент Navbar Bootstrap).

Мы также выполняем проверку условий с помощью {% if user.is_authenticated %} /{% endif %}, чтобы решить, показывать ли меню администратора или нет.

Наконец, помните, что, поскольку теперь мы поддерживаем два разных основных шаблона, нам нужно добавить HTML-код навигационной панели в оба, myapp/templates/myapp/template.html и templates/admin/base_site.html.

Дополнительно: экран входа администратора

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

Теперь мы можем превратить что-то вроде этого:

Source

… в что-то вроде этого:

Мы можем приблизиться к этому, создав следующий шаблон в templates/admin/login.html:

{% extends "admin/login.html" %}

{% load i18n static %}

{% block extrastyle %}
{{ block.super }}
<style>
#header {
  background-color: transparent !important;
}
</style>
{% endblock %}

{% block branding %}
<h1>
  <span style="color: #57C5A5 !important">ActionPlanNow.com</span>
  <br />
  <small>{% block head_title %}{% endblock %}</small>
</h1>
{% endblock %}

{% block content_title %}
<p class="lead" style="font-size: larger">
A Simple Tool for Leaders, Coaches, and Counselors.
</p>
{% endblock %}

Разбор

Что мы делаем здесь:

  1. Тег {{ block.super }} указывает движку шаблонов, что мы не переопределяем содержимое extrastyle (которое мы определили в шаблоне templates/admin/base_site.html), а просто добавляем к нему контент (см. наследование шаблонов для получения дополнительной информации).
  2. Блок branding позволяет нам изменить заголовок “Администрирование Django” на что-то более интересное.
  3. Мы избавляемся от блока head_title путем установки пустого определения.
  4. Мы используем блок content_title для добавления дополнительной информации.

Некоторые соображения

Source

Так же, как и Bootstrap, Django admin site поставляется с собственным набором jQuery, но, к счастью, разработчики Django продумали этот момент и, чтобы избежать конфликтов с пользовательскими скриптами и библиотеками, jQuery Django имеет пространство имен django.jQuery. Таким образом, мы можем безопасно включить свою собственную копию (как мы уже сделали).

Будьте осторожны при использовании множества определений классов в вашем основном стиле, так как это также повлияет на админ-сайт, влияя на его функциональность непредсказуемым образом. В таком случае вы всегда можете посмотреть, что происходит с помощью инструментов отладки вашего браузера, таких как Chrome DevTools, Firefox Developer Tools (особенно Page Inspector), или Safari Developer Tools.

Демо и полный код

Этот вариант реализации, о котором мы говорили, будет выглядеть следующим образом:

Вы можете ознакомиться со всем кодом проекта в моем репозитории GitHub, luzdealba / djangovuejs.

Заключение

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

И делать это совсем несложно. Вам нужно обратить внимание на то, как вы оборачиваете административный интерфейс, а также на то, как вы сочетаете сторонние библиотеки со своим собственным JavaScript-кодом и таблицами стилей. К счастью, вы можете очень легко интегрировать некоторые из них в административную часть, некоторые в остальную часть основного сайта, а некоторые — в обе.

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

Если вам нужен повод создать веб-приложение только для того, чтобы поиграться с административным интерфейсом Django, ознакомьтесь с прошлой неделей с руководством по прототипированию веб-приложения с Django и Vue.js — это очень весело. И если вы хотите углубить свои навыки работы с Django, библиотека SitePoint Premium предлагает множество ресурсов для вас.

Часто задаваемые вопросы (FAQ) о настройке администратора Django с Bootstrap

Каковы преимущества настройки администратора Django с Bootstrap?

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

Как добавить пользовательские действия в Django Admin?

Django Admin позволяет добавлять пользовательские действия, которые могут быть выполнены над выбранными объектами. Чтобы добавить пользовательское действие, необходимо определить функцию, которая выполняет желаемое действие над выбранными объектами. Эта функция должна принимать три параметра: администратор модели, запрос и запрос выбранных объектов. После того как вы определили эту функцию, вы можете добавить её в атрибут ‘actions’ вашего администратора модели. Это сделает действие доступным в выпадающем списке действий на странице изменения списка администратора.

Могу ли я настроить внешний вид и ощущения Django Admin с помощью Bootstrap?

Да, вы можете настроить внешний вид и ощущения Django Admin с помощью Bootstrap. Bootstrap — это фронтенд-фреймворк, который предоставляет различные шаблоны дизайна для типографии, форм, кнопок и других компонентов интерфейса. Интегрировав его с Django Admin, вы можете использовать эти шаблоны для создания более привлекательного и функционального админ-интерфейса. Вы можете настроить цвета, шрифты, макет и другие элементы дизайна вашего админ-интерфейса, чтобы соответствовать вашей корпоративной идентичности или личным предпочтениям.

Как добавить пользовательские фильтры в Django Admin?

Django Admin позволяет добавлять пользовательские фильтры, которые могут использоваться для фильтрации отображаемых объектов на странице изменения списка администратора. Чтобы добавить пользовательский фильтр, необходимо определить подкласс django.contrib.admin.SimpleListFilter. Этот подкласс должен определять две функции: lookups и queryset. Функция lookups должна возвращать список кортежей, каждый из которых представляет вариант фильтра. Функция queryset должна возвращать отфильтрованный запрос на основе выбранного варианта фильтра. После того, как вы определили этот подкласс, вы можете добавить его в атрибут ‘list_filter’ вашего администратора модели.

Могу ли я использовать Bootstrap с Django Admin без дополнительных пакетов?

Хотя возможно использовать Bootstrap с Django Admin без дополнительных пакетов, обычно проще и эффективнее использовать пакет, такой как django-admin-bootstrap. Этот пакет предоставляет тему на основе Bootstrap для Django Admin, что упрощает интеграцию Bootstrap с Django Admin. Он также предоставляет дополнительные функции, такие как адаптивный дизайн и пользовательское отображение форм, которые могут еще больше улучшить удобство использования и функциональность вашего админ-интерфейса.

Как я могу настроить поля формы в Django Admin?

Django Admin позволяет настраивать поля форм, используемые для создания или редактирования объектов. Для настройки поля формы необходимо переопределить метод ‘formfield_for_dbfield’ вашего администратора модели. Этот метод должен возвращать экземпляр поля формы, который будет использоваться для указанного поля базы данных. Вы можете настроить атрибуты поля формы, виджеты и поведение валидации в соответствии с вашими потребностями.

Могу ли я добавлять пользовательские представления в Django Admin?

Да, вы можете добавлять пользовательские представления в Django Admin. Чтобы добавить пользовательское представление, необходимо определить метод в вашем администраторе модели, который обрабатывает логику представления. Этот метод должен принимать запрос в качестве единственного параметра и возвращать ответ. Затем вы можете связать этот метод с URL, добавив шаблон URL в метод ‘get_urls’ вашего администратора модели. Это сделает представление доступным через интерфейс администратора.

Как я могу настроить отображение списка в Django Admin?

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

Можно ли использовать Django Admin для сложных моделей базы данных?

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

Как я могу улучшить производительность Django Admin?

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

Source:
https://www.sitepoint.com/how-to-hack-redesign-customize-the-django-admin-with-bootstrap/