Как сделать ответы на комментарии Django?
Всем привет. Я недавно реализовал комментарии к посту, но как реализовать ответы на комментарии - не знаю. Создал модель ответов на комментарии и связал её с моделью самих комментариев. Форму ответов вывел в шаблон через get_context_data, но тут возникла такая проблема, что форма выводится как надо, но почему-то она связана с формой самих комментариев. То есть форма ответов и форма комментариев - это одно и то же, хотя формы по виду разные.
Как я пытался это реализовать(в коде и самих словах есть ошибки, но это тренировочный проект) :
models.py
from django.db import models
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=100, verbose_name='Заголовок')
slug = models.SlugField(unique=True, verbose_name='URL', help_text='Уникальная ссылка на запись')
content = models.TextField(blank=True, verbose_name='Текс')
created = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания поста')
updated = models.DateTimeField(auto_now=True, verbose_name='Дата обновления поста')
image = models.ImageField(blank=True, upload_to='photo/%Y/%m/%d', verbose_name='Фото')
tags = models.ManyToManyField('tag', verbose_name='Тэг', blank=True)
categories = models.ForeignKey('category', on_delete=models.PROTECT, verbose_name='Категория', blank=True)
views = models.IntegerField(default=0, verbose_name='Кол-во просмотров')
class Meta:
verbose_name = 'Пост'
verbose_name_plural = 'Посты'
ordering = ['-created']
def get_absolute_url(self):
return reverse('single', kwargs={'url': self.slug})
def __str__(self) -> str:
return self.title
class Tag(models.Model):
name = models.CharField(max_length=50, verbose_name='Имя тэга')
slug = models.SlugField(unique=True, verbose_name='URL')
class Meta:
verbose_name = 'Тэг'
verbose_name_plural = 'Тэги'
def get_absolute_url(self):
return reverse('tag', kwargs={'url': self.slug})
def __str__(self) -> str:
return self.name
class Category(models.Model):
name = models.CharField(max_length=50, verbose_name='Название категории')
slug = models.SlugField(unique=True, verbose_name='URL')
class Meta:
verbose_name = 'Категория'
verbose_name_plural = 'Категории'
def get_absolute_url(self):
return reverse('category', kwargs={'url': self.slug})
def __str__(self) -> str:
return self.name
class Comment(models.Model):
name = models.CharField(max_length=100, blank=True)
comment = models.TextField(blank=True)
post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True, verbose_name='comment', blank=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Комментарий'
verbose_name_plural = 'Комментарии'
ordering = ['-created']
def __str__(self) -> str:
return f'{self.name} - {self.comment}'
class RepltCom(models.Model):
rep_name = models.CharField(max_length=100)
rep_comment = models.TextField()
rep_com = models.ForeignKey(Comment, on_delete=models.CASCADE, null=True)
rep_created = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Ответ'
verbose_name_plural = 'Ответы'
ordering = ['-rep_created']
def __str__(self) -> str:
return f'{self.rep_name} - {self.rep_comment}'
forms.py
from django import forms
from .models import *
class AddPost(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'slug', 'content','tags', 'image', 'categories']
class AddComment(forms.ModelForm):
class Meta:
model = Comment
fields = ['name', 'comment', 'post']
class AddReply(forms.ModelForm):
class Meta:
model = RepltCom
fields = ['rep_name', 'rep_comment', 'rep_com']
views.py
class Single(DetailView, CreateView):
model = Post
form_class = AddComment
template_name = 'a_blog/single.html'
context_object_name = 'single'
slug_url_kwarg = 'url'
def get_success_url(self) -> str:
return reverse('single', kwargs={'url': self.kwargs['url']})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
Post.objects.filter(slug=self.kwargs['url']).update(views=F('views') + 1)
context['reply_form'] = AddReply
return context
Сам шаблон single.html
{% extends 'a_blog/base.html' %}
{% load static %}
{% block content %}
<div class="container-fluid single-container">
<div class="row">
<div class="col-12">
<div class="date text-center">
{{ single.date }}
</div>
<div class="title text-center">
{{ single.title }}
</div>
<div class="img">
{% if single.image %}
<img src="{{ single.image.url }}" class="img-fluid w-100">
{% else %}
<img src="{% static 'images/no-image.png' %}" class="img-fluid w-100">
{% endif %}
</div>
<div class="content">
{{ single.content }}
</div>
{% if request.user.is_authenticated %}
<form method="post" id="comReply">
{% csrf_token %}
<p><label hidden for="{{ form.name.id_for_label }}">Автор: </label></p>
<input type="hidden" id="{{ form.name.id_for_label }}" name="name" value="{{ request.user.username }}">
<div>{{ form.name.errors }}</div>
<p><label for="{{ form.comment.id_for_label }}">Комментарий: </label>{{ form.comment }}</p>
<div>{{ form.comment.errors }}</div>
<p><label hidden for="{{ form.post.id_for_label }}">Пост: </label></p>
<select hidden id="{{ form.post.id_for_label }}" name="post">
<option value="{{ single.id }}">{{ single.title }}</option>
</select>
<div>{{ form.post.errors }}</div>
<button type="submit">aadd</button>
</form>
{% else %}
<h2>Войдите в аккаунт, чтобы оставить комментарий</h2>
{% endif %}
{% for com in single.comment_set.all %}
<p>{{ com.name }}</p>
<p>{{ com.comment }}</p>
<form method="post" id="comReply">
{% csrf_token %}
{{ reply_form.as_p }}
<button type="submit">aadd</button>
</form>
{% for rep in com.repltcom_set.all %}
<p class="bg-success reply">{{ rep.rep_name }}</p>
<p class="bg-success reply">{{ rep.rep_comment }}</p>
<hr>
{% endfor %}
<hr>
{% endfor %}
</div>
</div>
</div>
<script>
function addReply(id) {
document.getElementById('contactparent').value = id;
}
</script>
{% endblock %}
Нашел на этом же сайте такую штуку:
parent = models.ForeignKey('self', null=True, blank=True, related_name='replies')
Примерно понимаю, что оно делает, но не совсем. Если не сложно, прошу объяснить, что это, или дать ссылку на документацию.
Как правильно будет поступить: моим способом или же вторым?