Комментарии — это неотъемлемая часть любого интерактивного веб-сайта, и чтобы сделать их еще более функциональными, мы можем добавить возможность публикации комментариев в зависимости от статуса пользователя, а также реализовать автозаполнение полей формы, если пользователь залогинен. В этой статье мы подробно рассмотрим, как это сделать.
Основные задачи
- Добавление статусов комментариев — чтобы комментарии могли иметь различные статусы (например, ожидает модерации, опубликован, отклонен).
- Установка статуса комментария в зависимости от статуса пользователя — если пользователь имеет определенный статус (например, модератор или администратор), комментарий будет опубликован сразу, иначе будет ожидать модерации.
- Автозаполнение формы — если пользователь залогинен, его данные (например, имя пользователя и 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>
Объяснение:
- Мы добавили отображение статуса комментария рядом с именем пользователя.
- Форма для ответа автоматически заполняется данными пользователя, если он залогинен.
Итог
Теперь ваша система комментариев не только позволяет пользователям оставлять комментарии и отвечать на них, но и управляет публикацией на основе статуса пользователя. Также форма автоматически заполняется, если пользователь уже авторизован.
Возможные расширения:
- Реализовать уведомления для администраторов о новых комментариях, ожидающих модерации.
- Добавить возможность редактирования комментариев.
- Создать фильтры для отображения только опубликованных комментариев или комментариев с определенным статусом.
С помощью этих изменений ваш проект станет более интерактивным и удобным для пользователей!
Написать комментарий