Создание блога на Django 3 для начинающих

Блог на Django с нуля

В данном уроке мы займемся созданием блога на Django, которое позволит пользователям создавать, редактировать и удалять записи. На домашней странице сайта дается список всех записей блога, для каждой отдельной записи также будет предусмотрена детализированная страница. Помимо всего прочего, изучим как применяются CSS стили и рассмотрим принципы работы Django со статическими файлами, такие как css, js, jpg, png.

Содержание статьи

Начальная настройка блога на Django

Настройка нового Django проекта состоит из следующих этапов:

  • создание новой директории для кода на рабочем столе под названием blog;
  • установка Django в новом виртуальном окружении;
  • создание нового проекта под названием blog_project;
  • создание нового приложения blog;
  • осуществление миграции для установки базы данных;
  • обновление файла настроек settings.py.

Есть вопросы по Python?

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

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Не забудьте поставить точку . в конце команды для создания нового проекта blog_project.

Сообщим Django о новом приложении. Для этого откроем в текстовом редакторе файл settings.py и добавим в конце переменной INSTALLED_APPS наше приложение:

При переходе по адресу http://127.0.0.1:8000/ в браузере откроется следующая страница.

django app

Приветственная страница Django

Итак, установка завершена! Далее займемся созданием модели базы данных для записей блога.

Создание модели Post для работы с записями блога

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

  • Заголовок;
  • Автор;
  • Содержимое.

Все это можно превратить в модель базы данных, наполните файл blog/models.py следующим содержимым:

В верхней части импортируется класс models, а затем модель Post наследует класс models.Model. Используя функциональные особенности наследника, мы автоматически получаем доступ ко всем данным внутри родительского класса django.db.models.Models. Теперь можно добавлять дополнительные поля и все необходимые нам методы.

Для заголовка title ставим ограничение на 200 символов, а для содержимого статьи body используем тип TextField, что автоматические расширяется, подстраиваясь под длину текста пользователя. В Django доступно множество типов полей, с полным списком которых можете ознакомиться здесь.

Для поля автора author используем ForeignKey, что допускает взаимодействия по схеме многие-к-одному. Это значит, что любой пользователь может быть автором множества записей, но не иначе. Отталкиваемся от встроенной в Django модели User, предусмотренной для аутентификации. Для взаимоотношений многие-к-одному вроде ForeignKey требуется уточнить опцию on_delete чтобы знать как себя вести при удалении записи из одной таблицы которая связана с данными из других таблиц.

Теперь, когда новая модель базы данных создана, нужно создать новую запись миграции и перенести изменение в нашу базу данных. Остановите веб-сервер через комбинацию CTRL+C. Данный двухэтапный процесс можно выполнить используя данные команды:

База данных настроена! Что дальше?

Панель администратора для блога на Django

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

Теперь вновь запустим веб-сервер при помощи команды python manage.py runserver и откроем админку, перейдя по адресу http://127.0.0.1:8000/admin/. При входе укажите данные вашего аккаунта суперпользователя.

И где же новая модель Post для работы с записями блога?

blog

Домашняя страница панели администратора

Мы забыли обновить файл blog/admin.py. Давайте сделаем это сейчас.

Обновления в админке можно увидеть после перезагрузки страницы.

blog

Домашняя страница панели администратора

Добавим две записи, чтобы появились образцы для дальнейшей работы с блогом. Для создания нового поста нажмите кнопку + Add рядом с Posts. Не забудьте указать автора каждой записи, так как по умолчанию все поля в модели являются обязательными. Если попытаться опубликовать что-то без указания автора, выйдет ошибка. При желании поменять данное условие, можно добавить специальные опции для полей рассматриваемой модели, сделав поле необязательным или же заполнить его значением по умолчанию.

blog

Создание первой записи в блоге

blog

Создание второй записи в блоге

blog

Список записей блога в админке

С созданием модели базы данных все работы завершены. Теперь нужно создать все необходимые представления (Views), настройка URL маршрутов и создание файлов шаблона для отображения информации нашего блога на Django.

Настройка URL маршрутов для блога на Django

Для отображения записей блога на главной странице, настроим конфигурацию файла blog_project/urls.py, а также файла  blog/urls.py.

В командной строке выключаем запущенный веб-сервер через комбинацию CTRL+C и создаем новый файл urls.py внутри приложения blog:

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

В верхней части импортируем будущие представления. Пустые одинарные кавычки '' говорят Django принимать все значения и создать именованный URL home, к которому можно будет позже отсылаться из представлений (views). Хотя сейчас создавать именованный URL не обязательно, будет лучше, если вы выработаете у себя данную привычку. С ростом количества URL маршрутов это поможет сохранять проект более организованным и упорядоченным.

Мы также должны обновить файл blog_project/urls.py, чтобы в дальнейшем все запросы направлялись напрямую к приложению blog.

Мы добавили функцию include() на второй строке и URL паттерн, используя пустую строку регулярного выражения '', указывая, что URL запросы должны быть перенаправлены к обработчику URL маршрутов от приложения blog для последующих инструкций.

Представления — BlogListView для отображения записей блога

Сейчас мы будем использовать классовые представления, однако при создании приложения для блога также можно применить функционально-ориентированный подход. При желании более подробно изучить второй вариант можете ознакомиться с уроками от Django Girls Tutorial. Отличная вещь!

В файле views.py добавьте указанный ниже код, который нужен для отображения содержимого из модели Post при использовании ListView от Django.

Первые две строчки импортируют ListView и модель нашей базы данных Post. Мы наследуем класс ListView и добавляем отсылку к модели и указываем на HTML файл шаблона. Это позволяет сэкономить на коде, избавляя от необходимости написания дополнительного кода с нуля.

Создание шаблона для блога на Django

Настройка URL маршрутов и представления готовы, остались только разобраться с шаблонами. Здесь можно унаследовать свойства других шаблонов, чтобы сохранить текущий код чистым. Начнем с файла base.html и файла home.html, который наследует структуру от него. Затем создадим шаблоны для создания и редактирования записей блога, который также могут наследовать основную структуру от base.html.

Создадим новую директорию templates и два HTML файла шаблонов внутри нее.

Теперь обновляем файл settings.py, для того чтобы Django понимал в какие еще директории искать наши файлы шаблона.

Затем обновляем шаблон base.html следующим образом.

Обратите внимание, что место между {% block content %} и {% endblock content %} будет заполнено содержимым из других файлов, например home.html.

В верхней части файла можно заметить, что данный шаблон расширяет базовый base.html и затем заполняет блок content данными. Используя специальный язык шаблонов мы применяем цикл for для отображения всех записей. Обратите внимание, что переменная object_list досталось нам от класса ListView и содержит все объекты нашего представления.

Если опять запустить веб-сервер через python manage.py runserver и затем перезагрузить страницу http://127.0.0.1:8000/, можно убедиться, что все работает.

blog

Домашняя страница блога с двумя записями

Выглядит, конечно, не очень. Давайте исправим ситуацию при помощи добавления CSS стилей.

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

Сейчас нам потребуется использовать CSS стили, что по сути являются статическими файлами, так как в отличие от динамического содержимого базы данных, они не меняются. К счастью, в Django можно напрямую добавить статические файлы вроде CSS, JavaScript или изображения.

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

Закрываем локальный веб-сервер через CTRL+C. Создаем новую директорию под названием static.

Как и в случае с директорией templates, сейчас нам понадобится обновить файл settings.py для уведомления Django о месте поиска статических файлов. В settings.py потребуется изменить переменную STATICFILES_DIRS. Внесем изменения в нижнюю часть файла под переменной STATIC_URL.

Теперь внутри static создаем директорию css и добавляем новый файл base.css в нее.

Что добавить в файл? Может, поменяем цвет заголовка на красный?

В конце нужно включить статические файлы в наши шаблоны, добавив {% load static %} в верхнюю часть base.html. Так как остальные шаблоны унаследуют каркас от base.html, то редактировать надо будет только этот файл. Добавляем новую строку в шаблоне, она напрямую отсылает к новому файлу base.css.

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

Заново запускаем веб-сервер через команду python manage.py runserver и смотрим на изменения в обновленной домашней странице http://127.0.0.1:8000/.

blog

Домашняя страница блога с красным заголовком

Давайте изменим еще что-то. Как насчет нового шрифта? Давайте просто вставим следующий код бесплатного шрифта Source Sans Pro от Google между тегами <head></head>.

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

Перезагрузив домашнюю страницу http://127.0.0.1:8000/, вы увидите следующее.

blog

Домашняя страница блога с CSS

Создаем отдельную страницу DetailView для статьи

Теперь можно добавить функционал для индивидуальных страниц блога. Как это сделать? Понадобится новое представление (view), настройка url маршрута и HTML шаблон. Надеюсь, вы уже уловили суть и правила разработки c Django.

Начнем с представления. Для простоты можем использовать общий класс DetailView. В верхней части файла импортируем DetailView и затем создаем новое представление под названием BlogDetailView.

В новом представлении мы указываем на используемую модель Post, а также на файл HTML шаблона, с которым нужно ее ассоциировать — post_detail.html. По умолчанию DetailView предоставляет объект содержимого модели, которого мы можем использовать в шаблоне для получения данных о статье, название переменной зависит от названия модели, в нашем случае это post. Кроме того, класс DetailView запрашивает первичный ключ (ID), либо slug в качестве идентификатора требуемой нами записи из БД. Скоро поговорим и об этом.

Закрываем локальный веб-сервер через CTRL+C и создаем новый HTML шаблон для просмотра записей на отдельной странице:

Далее набираем следующий код:

В верхней части уточняется, что данный шаблон наследует структуру от base.html. Затем показывается заголовок и содержимое статьи из объекта post, данную переменную предоставляет общий класс представления DetailView в зависимости от названия нашей модели.

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

Если использование post или object кажется вам запутанным, можно напрямую именовать объект содержимого в представлении, задействовав context_object_name.

«Магическое» именование объекта содержимого становится своего рода платой за простоту использования общих представлений (generic views). Они являются отличным вариантом, если известен их функционал, поэтому лучше заранее ознакомиться с особенностями настройки в официальной документации.

Что дальше? Добавим новый URL маршрут для работы с отдельными статьями в зависимости от их ID.

Все записи блога будут начинаться с post/. Рассмотрим первичный ключ для записи, который будет представлен целым числом <int:pk>. Что такое первичный ключ, спросите?

Django автоматически добавляет автоинкрементный первичный ключ к модели базы данных. В то время, как мы просто обозначили поля title, author и body в модели Post, Django автоматически добавил еще одно поле под названием id, которое и является первичным ключом. Получить к нему доступ можно через id или pk.

У первой записи «Hello, Worl» pk будет 1. У второй записи ID = 2. И так далее. Следовательно, если перейти на индивидуальную страницу первого поста, структура его url будет post/1.

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

Теперь, если запустить веб-сервер через команду python manage.py runserver и перейти по адресу http://127.0.0.1:8000/post/1/, можно увидеть отдельную индивидуальную страницу для первой записи блога.

django blog

Детали первой записи блога

Ура! Следовательно, перейдя по адресу http://127.0.0.1:8000/post/2/, вы увидите индивидуальную страницу второй записи. Для простоты обновим ссылку на домашней страницы, чтобы получить доступ ко всем записям оттуда. На данный момент ссылка <a href=""> в файле home.html пуста. Обновим ее как <a href="{% url 'post_detail' post.pk %}">.

Начнем с указания шаблону о необходимости отсылки к настройкам из URLConf, для чего используем код {% url ... %}. Какой URL? Тот самый под названием post_detail, что является именем, которое мы недавно дали BlogDetailView в переменной URLConf. Если посмотреть на post_detail в URLConf, то увидим, что он ждет передачи аргумента pk, который представляет первичный ключ записи блога. К счастью, Django уже создал и включил поле pk для объекта post. Мы передаем его в URLConf при добавлении в шаблон как post.pk.

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

Пишем TestCase для блога на Django

Теперь нужно проверить нашу модель и представления (views). Необходимо убедиться, что модель Post работает как надо. Также протестируем общие классы представлений ListView и DetailView.

Образец тестов в blog/tests.py будет выглядеть следующим образом.

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

В метод setUp добавляется образец записи блога для тестирования и дальнейшего подтверждения, что строки и содержимое работают верно. Затем используется test_post_list_view, который подтверждает, что домашняя страница возвращает HTTP код состояния 200, содержит правильный текст в теге body и использует правильный шаблон home.html. В конечном итоге test_post_detail_view проверяет, работает ли индивидуальная страница записи правильно, а поврежденная страница возвращает ошибку 404. В тестах полезно проводить проверку как на наличие определенных данных, так и на отсутствие разнообразных ошибок.

Можете выполнить тесты прямо сейчас. Все должно сработать.

Загружаем файлы блога на Github

Пришло время для коммита изменений на github. Начинаем с инициализации нашей директории.

Затем осматриваем все изменения и добавления в коде, через команду status. Добавляем все новые файлы. После этого делаем первый коммит.

Заключение

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