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

我正在使用Django创建自己的博客,并且已经建立了一个Comment系统。.我想为每个评论添加回复(如普通评论框一样),但我不知道该怎么做才是当前模型。注释:

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)
  • 记得运行makemigrationsmigrate
  • 2.让我们从观点开始。我正在使用post_detail视图以显示帖子及其评论。我们添加一个QuerySet来检索此帖子的所有父活动注释。之后,我们使用表单的is_valid()验证提交的数据。如果表单有效,我们将检查提交的数据是否来自重播按钮表单中的隐藏输入。接下来,如果parent_id退出,我们为重播注释和parent_obj对象创建父对象(replay_comment),然后将parent_obj分配给replay_comment
    如果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')
    

    *有关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即可使回复评论淡出,仅此而已。

    python JSON对象必须是str,bytes或bytearray,而不是'dict - python

    在Python 3中,要加载以前保存的json,如下所示:json.dumps(dictionary)输出是这样的{"('Hello',)": 6, "('Hi',)": 5}当我使用json.loads({"('Hello',)": 6,…

    单行的'if'/'for'语句是否使用Python样式好? - python

    我经常在这里看到某人的代码,看起来像是“单线”,这是一条单行语句,以传统的“if”语句或“for”循环的标准方式执行。我在Google周围搜索,无法真正找到可以执行的搜索类型?任何人都可以提出建议并最好举一些例子吗?例如,我可以一行执行此操作吗?example = "example" if "exam" in exam…

    为什么使用'=='或'is'比较字符串有时会产生不同的结果? - python

    我有一个Python程序,其中将两个变量设置为'public'值。在条件表达式中,我有比较var1 is var2失败,但如果将其更改为var1 == var2,它将返回True。现在,如果我打开Python解释器并进行相同的“是”比较,则此操作成功。>>> s1 = 'public' >>…

    当我运行python代码时,它说“ <<目前是意外情况” - python

    基本上,这是我们合作者的python代码,用于生成网格,该网格是在Linux环境下开发的。我使用Cygwin在Windows上运行此代码。麻烦部分如下。 BiV_temp.geo也是一个python脚本。因此,命令是用预定义的数字和文件名替换脚本BiV_temp.geo中的字符串。os.system('cp BiV_fiber.geo BiV_te…

    Python Pandas导出数据 - python

    我正在使用python pandas处理一些数据。我已使用以下代码将数据导出到excel文件。writer = pd.ExcelWriter('Data.xlsx'); wrong_data.to_excel(writer,"Names which are wrong", index = False); writer.…