# Комментарии на сайте --- ## модель комментариев ---- Сделаем так, чтобы зарегистрированные пользователи могли оставлять комментарии беспрепятственно, а гости должны были дополнительно ввести 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 %} ```
{"metaMigratedAt":"2023-06-16T16:33:58.145Z","metaMigratedFrom":"Content","title":"Комментарии на сайте","breaks":true,"contributors":"[{\"id\":\"0d39d5a3-691d-488c-8f1e-1a0fb0be4f13\",\"add\":4106,\"del\":12}]"}
    219 views