L o a d i n g
Расширение функционала комментариев в Django: публикация комментариев в зависимости от статуса пользователя и автозаполнение формы Парсинг данных

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

Основные задачи

  1. Добавление статусов комментариев — чтобы комментарии могли иметь различные статусы (например, ожидает модерации, опубликован, отклонен).
  2. Установка статуса комментария в зависимости от статуса пользователя — если пользователь имеет определенный статус (например, модератор или администратор), комментарий будет опубликован сразу, иначе будет ожидать модерации.
  3. Автозаполнение формы — если пользователь залогинен, его данные (например, имя пользователя и email) будут автоматически подставляться в форму комментария.

Шаг 1: Модель комментариев с поддержкой статусов

Для начала нам нужно расширить модель Comment, добавив поле для статуса комментария. Статус может быть представлен как CharField, где мы можем использовать выбор из нескольких вариантов.

from django.db import models
from django.contrib.auth.models import User

class Comment(models.Model):
    STATUS_CHOICES = [
        ('pending', 'Ожидает модерации'),
        ('approved', 'Опубликован'),
        ('rejected', 'Отклонен'),
    ]

    user = models.ForeignKey(User, on_delete=models.CASCADE)  # Пользователь, оставивший комментарий
    post = models.ForeignKey('Post', on_delete=models.CASCADE)  # Пост, к которому относится комментарий
    content = models.TextField()  # Текст комментария
    parent = models.ForeignKey('self', null=True, blank=True, related_name='replies', on_delete=models.CASCADE)  # Ссылка на родительский комментарий
    created_at = models.DateTimeField(auto_now_add=True)  # Дата создания комментария
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending')  # Статус комментария

    class Meta:
        ordering = ['created_at']  # Комментарии будут сортироваться по дате создания

    def __str__(self):
        return f'{self.user.username} - {self.content[:20]} ({self.get_status_display()})'  # Для удобного отображения комментария в админке

    def is_reply(self):
        return self.parent is not None  # Проверяем, является ли комментарий ответом

Объяснение:

  • Мы добавили поле status с выбором из трех статусов: "Ожидает модерации", "Опубликован", и "Отклонен".
  • Метод __str__ теперь отображает статус комментария для удобства.

Шаг 2: Логика представлений для обработки статусов

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

from django.shortcuts import render, get_object_or_404, redirect
from .models import Post, Comment
from .forms import CommentForm

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)  # Загружаем пост по слагу
    comments = post.comment_set.filter(parent__isnull=True)  # Загружаем только корневые комментарии
    form = CommentForm(initial={'user': request.user}) if request.user.is_authenticated else CommentForm()  # Автозаполнение формы

    if request.method == 'POST':  # Обработка формы
        form = CommentForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.user = request.user  # Привязываем комментарий к пользователю
            new_comment.post = post  # Привязываем комментарий к посту
            
            # Устанавливаем статус в зависимости от статуса пользователя
            if request.user.is_staff:  # Если пользователь - модератор или администратор
                new_comment.status = 'approved'  # Комментарий сразу публикуется
            else:
                new_comment.status = 'pending'  # Ожидает модерации
            
            parent_id = request.POST.get('parent_id')  # Проверяем, если это ответ
            if parent_id:
                new_comment.parent = Comment.objects.get(id=parent_id)  # Привязываем к родительскому комментарию
            
            new_comment.save()  # Сохраняем комментарий
            return redirect('post_detail', slug=post.slug)  # Перенаправляем обратно на пост

    context = {
        'post': post,
        'comments': comments,
        'form': form,
    }
    return render(request, 'post_detail.html', context)

Объяснение:

  • Мы проверяем, залогинен ли пользователь, и если да, заполняем поля формы его данными.
  • Если пользователь является модератором или администратором (request.user.is_staff), комментарий публикуется сразу. В противном случае статус устанавливается в "Ожидает модерации".

Шаг 3: Шаблон для отображения комментариев и формы

Теперь обновим шаблон, чтобы он отображал статус комментария и автозаполнял форму.

<div class="post-content">
    <h2>{{ post.title }}</h2>
    <p>{{ post.content }}</p>
</div>

<div class="comments-section">
    <h3>Комментарии</h3>
    {% for comment in comments %}
        <div class="comment">
            <p><strong>{{ comment.user.username }}</strong> ({{ comment.get_status_display }})</p>
            <p>{{ comment.content }}</p>
            <p><small>{{ comment.created_at }}</small></p>
            <a href="#" class="reply-btn" data-comment-id="{{ comment.id }}">Ответить</a>

            <div class="replies">
                {% for reply in comment.replies.all %}
                    <div class="reply">
                        <p><strong>{{ reply.user.username }}</strong> ({{ reply.get_status_display }})</p>
                        <p>{{ reply.content }}</p>
                        <p><small>{{ reply.created_at }}</small></p>
                    </div>
                {% endfor %}
            </div>

            <form method="POST" class="reply-form" style="display:none;">
                {% csrf_token %}
                {{ form }}
                <input type="hidden" name="parent_id" value="{{ comment.id }}">
                <button type="submit" class="btn btn-primary">Отправить</button>
            </form>
        </div>
    {% endfor %}
</div>

<form method="POST">
    {% csrf_token %}
    {{ form }}
    <button type="submit" class="btn btn-primary">Добавить комментарий</button>
</form>

Объяснение:

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

Итог

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

Возможные расширения:

  • Реализовать уведомления для администраторов о новых комментариях, ожидающих модерации.
  • Добавить возможность редактирования комментариев.
  • Создать фильтры для отображения только опубликованных комментариев или комментариев с определенным статусом.

С помощью этих изменений ваш проект станет более интерактивным и удобным для пользователей!

Написать комментарий

Вы можете оставить комментарий автору статьи Обязательные поля помечены *