Django 4: Мини-блог с отдельными страницами записей и комментариями

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

Представление для отдельной страницы записи

Создадим представление для отрисовки отдельной страницы записи. Добавим класс в views.py:

class PostDetail(View):
    """Отдельная страница записи."""
    def get(self, request, pk):
        post = Post.objects.get(pk=pk)
        return render(request, 'blog/blog_detail.html', {'post': post})

PostDetail наследуется от View. Метод get принимает запрос и pk (первичный ключ) записи. Он получает запись из базы данных с помощью Post.objects.get(pk=pk) и передает её в шаблон blog/blog_detail.html через контекст {‘post’: post}.

Настройка URL-адресов

Настроим URL-адреса для доступа к отдельным страницам записей. Добавим в urls.py:

path('<int:pk>/', PostDetail.as_view(), name='post_detail'),

Это добавит URL-адрес вида /номер_записи/, где номер_записи — первичный ключ записи. int:pk указывает, что pk — целое число. PostDetail.as_view() указывает на наше представление.

Шаблон для отдельной страницы записи

Создадим HTML-шаблон blog/blog_detail.html. Структура похожа на шаблон главной страницы, но выводится информация только об одной записи:

<!DOCTYPE html>
<html>
  <head>
    <title>{{ post.title }}</title>
  </head>
  <body>
    <h1>{{ post.title }}</h1>
    <p style="text-align: center;">
      <img src="{{ post.image }}" style="width: 50%;">
    </p>
    <p>{{ post.text }}</p>
    <p>Автор: {{ post.author }}</p>
  </body>
</html>

Шаблон использует данные из объекта post, переданного из представления. Изображение выводится по центру с шириной 50% родительского блока.

Ссылки на отдельные страницы в главном шаблоне

В главном шаблоне blog.html заменим заголовки записей на ссылки с помощью тега <a>:

<a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a>

Это создаст ссылку на страницу отдельной записи, используя URL, генерируемый Django.

Модель для комментариев

Создадим модель Comment в models.py для хранения комментариев:

class Comment(models.Model):
    """Модель для комментариев."""
    email = models.EmailField()
    name = models.CharField(max_length=50)
    text = models.TextField(max_length=2000)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

    def __str__(self):
        return f'Комментарий от {self.name} к посту {self.post}'

Модель содержит поля для email, имени, текста комментария и внешний ключ post, связывающий комментарий с записью. on_delete=models.CASCADE обеспечивает каскадное удаление комментариев при удалении записи.

Миграции

Создадим и применим миграции:

python manage.py makemigrations
python manage.py migrate

Это создаст таблицу для хранения комментариев в базе данных.

Регистрация модели в админке

Зарегистрируем модель Comment в админке в admin.py:

from django.contrib import admin
from .models import Comment

admin.site.register(Comment)

Форма для отправки комментариев в шаблоне

Добавим форму для отправки комментариев в blog/blog_detail.html:

<div class="form-comment">
  <h3>Оставить комментарий</h3>
  <form method="post" action="#">
    <label for="text_comment">Ваш комментарий:</label><br>
    <textarea id="text_comment" name="text_comment"></textarea><br>
    <label for="name">Ваше имя:*</label><br>
    <input type="text" id="name" name="name"><br>
    <label for="email">Ваш email:</label><br>
    <input type="email" id="email" name="email"><br>
    <input type="submit" value="Отправить">
  </form>
</div>

Форма содержит поля для текста комментария, имени и email пользователя, а также кнопку «Отправить». Атрибуты name полей соответствуют полям модели Comment.

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

Что будем искать? Например,программа