changed 4 years ago
Published Linked with GitHub

Комментарии на сайте


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


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

Установим библиотеку Django Simple Captcha:

pipenv install django-simple-captcha


Добавим в список зарегистрированных в проекте приложение captcha— программное
ядро этой библиотеки:

INSTALLED_APPS = [
    ...
    'captcha',
]

И объявим в списке маршрутов уровня проекта (модуль urls.py пакета конфигурации)
маршрут, указывающий на это приложение:

urlpatterns = [
    path('captcha/', include('captcha.urls')),
    path('', include('main.urls')),
]

Код, объявляющий модель comment

class Comment(models.Model):
    bb = models.ForeignKey(Bb, on_delete=models.CASCADE, verbose_name='Объявление')
    author = models.CharField(max_length=30, verbose_name= 'Автор')
    content = models.TextField(verbose_name='Содержание')
    is_active = models.BooleanField(default=True, db_index=True, verbose_name='Выводить на экран?')
    created_at = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='Опубликован')
    
    class Meta:
        verbose_name_plural = 'Комментарии'
        verbose_name = 'Комментарий'
        ordering = ['created_at']

Реализация комментариев


Объявим связанные С моделью Comment формы UserCommentForm И GuestCommentForm, в которые будут заносить комментарии, соответственно, зарегистрированные пользователи, выполнившие вход, и гости.

from captcha.fields import CaptchaField

from .models import Comment

class UserCommentForm(forms.ModelForm):

    class Meta:
        model = Comment
        exclude = ('is_active',)
        widgets = {'bb': forms.HiddenInput}

class GuestCommentForm (forms. ModelForm):
    captcha = CaptchaField(label='Введите текст с картинки',
    error_messages={'invalid': 'Неправильный текст'})
    
    class Meta:
        model = Comment
        exclude = ('is_active',)
        widgets = {'bb': forms.HiddenInput}

Теперь необходимо существенно обновить код контроллера-функции detail(), реализовав в нем вывод комментариев и добавление нового комментария.

from .models import Comment

from .forms import UserCommentForm, GuestCommentForm

def detail(request, rubric_pk, pk):
    bb = Bb.objects.get(pk=pk)
    ais = bb.additionalimage_set.all()
    comments = Comment.objects.filter(bb=pk, is_active=True)
    initial = {'bb': bb.pk}
    if request.user.is_authenticated:
        initial['author'] = request.user.username
        form_class = UserCommentForm
    else:
        form_class = GuestCommentForm
    form = form_class(initial=initial)
    if request.method == 'POST':
        c_form = form_class(request.POST)
        if c_form.is_valid():
            c_form.save()
            messages.add_message(request, messages.SUCCESS, 'Комментарии добавлен')
        else:
            form = c_form
            messages.add_message(request, messages.WARNING, 'Комментарий не добавлен')
    context = {'bb': bb, 'ais': ais, 'comments': comments, 'form': form}
    return render(request, ’main/detail.html’, context)

В шаблоне main\detail.html отыщем тег шаблонизатора block content endblock и вставим перед закрывающим тегом код, выводящий комментарии:

...
{% load bootstrap4 %}
...
{% block content %}
    ...
    <h4 class="mt-5">Новый комментарий</h4>
    <form method="post">
        {% csrf_token %}
        {% bootstrap_form form layout='horizontal' %}
        {% buttons submi t='Добавить' %} {% endbuttons %}
    </form>
    {% if comments %}
        <div class="mt-5">
            {% for comment in comments %}
                <div class="my-2 p-2 border">
                    <h5>{{ comment.author }}</h5>
                    <p>{{ comment.content }}</p>
                    <p class="text-right font-italic">{{ comment.created_at }}</p>
                </div>
            {% endfor %}
        </div>
    {% endif %}
{% endblock %}
Select a repo