如何在 Django 中添加对评论的回复?

2024-02-28

我正在用 Django 制作自己的博客,并且我已经制作了一个评论系统。我想为每个评论添加回复(就像普通的评论框),但我不知道该怎么做,这是我当前的 models.py评论:

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.TextField()
    created_date = models.DateField(auto_now_add=True)
    parent = models.ForeignKey('self', null=True, related_name='replies')

    def __str__(self):
        return self.text

这是我使用注释的 .html

  {% for comment in post.comments.all %}
 <ul>
  {{ comment.text }}
  {% for reply in comment.replies.all %}
      <li>
          {{ reply.text }}
      </li>
  {% endfor %}
 <ul>
 {% endfor %}

显然它正在工作,但是当我尝试在 Django 的管理站点中发表评论时,它迫使我为每个评论添加一个“父级”(这不是强制性的,因为并非每个评论都是回复)我也不这样做知道如何在 HTML 文件中添加回复“按钮”。请帮助告诉我可以做哪些更改来制作一个带有回复的简单评论框。多谢


我遇到了同样的问题并解决如下:

1. 对于上面提到的管理站点只需设置blank=True对于父字段。我的评论模型:

class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='comments')
    name = models.CharField(max_length=80)
    email = models.EmailField(max_length=200, blank=True)
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    # manually deactivate inappropriate comments from admin site
    active = models.BooleanField(default=True)
    parent = models.ForeignKey('self', null=True, blank=True, related_name='replies')

    class Meta:
        # sort comments in chronological order by default
        ordering = ('created',)

    def __str__(self):
        return 'Comment by {}'.format(self.name)
  • 记得跑makemigrations and migrate

2.让我们从视图开始。我正在使用post_detail视图显示帖子及其评论。我们添加一个查询集来检索此帖子的所有父级活跃评论。之后,我们使用表单验证提交的数据is_valid()。如果表单有效,我们将检查提交的数据是否来自重播按钮表单中的隐藏输入。接下来如果parent_id退出我们创建父对象(parent_obj)用于重播评论和replay_comment对象,然后我们分配parent_obj to replay_comment. If parent_obj等于None我们只是通过创建来继续正常评论new_comment对象并将其保存到数据库中。

def post_detail(request, post):
    # get post object
    post = get_object_or_404(Post, slug=post)
    # list of active parent comments
    comments = post.comments.filter(active=True, parent__isnull=True)
    if request.method == 'POST':
        # comment has been added
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            parent_obj = None
            # get parent comment id from hidden input
            try:
                # id integer e.g. 15
                parent_id = int(request.POST.get('parent_id'))
            except:
                parent_id = None
            # if parent_id has been submitted get parent_obj id
            if parent_id:
                parent_obj = Comment.objects.get(id=parent_id)
                # if parent object exist
                if parent_obj:
                    # create replay comment object
                    replay_comment = comment_form.save(commit=False)
                    # assign parent_obj to replay comment
                    replay_comment.parent = parent_obj
            # normal comment
            # create comment object but do not save to database
            new_comment = comment_form.save(commit=False)
            # assign ship to the comment
            new_comment.post = post
            # save
            new_comment.save()
            return HttpResponseRedirect(post.get_absolute_url())
    else:
        comment_form = CommentForm()
    return render(request,
                  'core/detail.html',
                  {'post': post,
                   'comments': comments,
                   'comment_form': comment_form})

简单的评论表格:

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('name', 'email', 'body')

* 更多关于模型表单 https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#modelform

最后是模板。我们需要创建两个表单。一种用于评论,另一种用于重播。这里有简单的模板:

<!-- Comments Form --> 
<h2>Add a new comment</h2>
<form action="." method="post">
    {{ comment_form.as_p }}
    {% csrf_token %}
    <button type="submit">Add comment</button>
</form>

<!-- Comment with nested comments -->
{% for comment in comments %}
    <div class="comment" style="background-color: powderblue">
        <p class="info">{{ comment.name }} | {{ comment.created }}</p>
            {{ comment.body|linebreaks }}

        {% for replay in comment.replies.all %}
            <p class="info">{{ replay.name }} | {{ replay.created }}</p>
            <li>{{ replay.body }}</li>
        {% endfor %}

        <h5>Replay</h5>
        <form action="." method="post">
            {{ comment_form.as_p }}
            {% csrf_token %}
            <!-- Hidden input for parent comment.id -->
            <input type="hidden" name="parent_id" value="{{ comment.id }}">
            <input class="btn btn-primary" type="submit" value="Replay">
        </form>
    </div>
{% empty %}
<h4>There are no comments yet.</h4>
{% endfor %}

只需添加一些漂亮的 css 和 jquery 即可淡入回复评论,仅此而已。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Django 中添加对评论的回复? 的相关文章

随机推荐