简体   繁体   English

Django-实现线程注释的正确方法

[英]Django - proper way to implement threaded comments

I'm developing a blog site using Django. 我正在使用Django开发博客站点。 My site will allow users to comment on any of my blog posts and also reply to each other and will be displayed using a 'threaded comments' structure (I haven't started user functionality yet, just comments). 我的网站将允许用户在我的任何博客文章中发表评论并互相回复,并使用“线程评论”结构进行显示(我尚未启动用户功能,仅是评论)。 I've got the threaded comments to work properly using django-mptt (at least, for now), but I have NO CLUE if the route or steps I'm taking are in the right direction. 我已经使用django-mptt使线程注释正常工作(至少现在是这样),但是如果我选择的路线或方向正确,我将一无所知。 Almost all the tutorials I've gone through only scratch the surface when it comes to comments and doesn't talk about threaded comments in django. 当涉及到注释时,我所经历的几乎所有教程都只是从头开始,而没有涉及django中的线程注释。 I want some experienced/professional advice on what I might be doing wrong and what I could be doing better. 对于我可能做错了什么以及我可以做得更好的事情,我需要一些经验丰富/专业的建议。 The last thing I want is to find out there was a much more acceptable way of going about, after hours of work put in. 我要做的最后一件事是,经过数小时的工作,发现有一种更可接受的方法。

So, here is a list of what I need clarity on: 因此,这是我需要澄清的清单:

  1. django-mptt: django-mptt:

    • I chose this because I can afford slower write times. 我之所以选择它,是因为我负担得起更慢的写入时间。 My site will have more reads than writes. 我的网站的读写次数更多。 Is this option okay for my case? 这个选项适合我的情况吗? Is there a better alternative I don't know about? 有我不知道的更好的选择吗?
    • What should I do if my site does end up having lots of commenting activity? 如果我的站点确实有很多评论活动,该怎么办? What could I do to optimize tree restructuring? 我该怎么做才能优化树的重组? Or would I be better off switching to an adjacency list? 还是我最好切换到邻接表?
    • My MPTT comment model has a ForeignKey referenced to itself (for replies). 我的MPTT注释模型有一个指向其自身的ForeignKey(用于答复)。 Is this the right way? 这是正确的方法吗? Or should I create a separate reply model? 还是应该创建一个单独的回复模型?
    • The way I insert a reply to another user's comment in the tree is using a hidden input within the form that's within the mptt recursive template tags, and return the input value (which is the id of the comment that the reply is for) and set the parent of the reply to that input value. 我在树中插入对另一个用户的评论的回复的方法是在mptt递归模板标记内的表单中使用隐藏的输入,然后返回输入值(这是回复所针对的评论的ID)并进行设置该输入值的回复的父级。 Is this an accepted method? 这是公认的方法吗?
  2. Multiple forms on one HTML page 一个HTML页面上有多种表单

    • I have two forms on my blog post HTML page. 我的博客文章HTML页面上有两种形式。 One to comment on the blog post, and one to reply to a user's comment. 一个在博客上发表评论,一个在回复用户评论。 Is this accepted? 这被接受吗? Or should I create different URLs and view functions for different forms? 还是应该创建不同的URL并查看不同形式的函数? I did it this way because I wanted a Reddit style commenting system. 我这样做是因为我想要Reddit风格的评论系统。 I don't want it to have to go to a different page to comment or reply. 我不希望它必须转到其他页面来发表评论或回复。
    • If a user comments on my blog post, the hidden input value within the reply form returns nothing, therefore I get an error when trying to assign it to a variable in the views.py function. 如果用户对我的博客帖子发表评论,则答复表单中的隐藏输入值将不返回任何内容,因此在尝试将其分配给views.py函数中的变量时出现错误。 I used a try/except block to fix it. 我使用了try / except块来修复它。 Is there a better way around this? 有没有更好的办法解决这个问题?

I'm sorry if these are noob questions and for my post being so long. 很抱歉,如果这些不是菜鸟问题,并且我的帖子这么长。 I just want to do things the best way possible using realistic solutions for a beginner. 我只想为初学者使用可行的解决方案以最佳方式做事。 Any feedback would help. 任何反馈将有所帮助。 Thank you! 谢谢! Here's my code for my blog app. 这是我的博客应用程序的代码。

models.py models.py

    from django.db import models

    from mptt.models import MPTTModel, TreeForeignKey

    class Post(models.Model):
        """Blog post"""
        title = models.CharField(max_length=200)
        body = models.TextField()
       date_added = models.DateTimeField(auto_now_add=True)

        def __str__(self):
            return self.body[:50] + '...'

    class Comment(MPTTModel):
        """User comment"""
        post = models.ForeignKey(Post, related_name='comments',on_delete=models.CASCADE)
        parent = TreeForeignKey('self', null=True, blank=True, related_name='children',db_index=True, on_delete=models.CASCADE)

        user_comment = models.CharField(max_length=500, unique=True)
        date_added = models.DateTimeField(auto_now_add=True)
        # approved = models.BooleanField(default=False)

        class MPTTMeta:
            order_insertion_by = ['date_added']

        def __str__(self):
            return self.user_comment[:20]

'approved' is commented out because I get a 'no such column: approved' error for some weird reason. 由于某些奇怪的原因,我收到“没有这样的专栏:已批准”错误,因此将“批准”注释掉。

forms.py 表格

    from django import forms

    from .models import Post, Comment

    class CommentForm(forms.ModelForm):
        class Meta:
            model = Comment
            fields = ['user_comment']

views.py views.py

    from django.shortcuts import render
    from django.http import HttpResponseRedirect
    from django.urls import reverse

    from .models import Post
    from .forms import CommentForm

    def posts(request):
        """Show all blog posts"""

        posts = Post.objects.order_by('-date_added')

        context = {
            'posts': posts
        }
        return render(request, 'posts/posts.html', context)

    def post(request, post_id):
        """Show single blog post"""

        post = Post.objects.get(id=post_id)
        comments = post.comments.all()

        if request.method != 'POST':
            comment_form = CommentForm()

        else:
            comment_form = CommentForm(data=request.POST)
            try:
                parent_id = request.POST['comment_id']
            except:
                pass
            if comment_form.is_valid():
                comment = comment_form.save(commit=False)
                comment.post = post
                comment.parent = comments.get(id=parent_id)
                comment.save()
                return HttpResponseRedirect(reverse('posts:post', args=[post_id]))

        context = {
            'post': post,
            'comment_form': comment_form,
            'comments': comments,
        }
        return render(request, 'posts/post.html', context)

post.html post.html

    {% extends 'posts/base.html' %}

    {% block blog_content %}

        <h1>Post page!</h1>

        <h3>{{ post.title }}</h3>
        <h4>{{ post.date_added }}</h4>
        <p>{{ post.body }}</p>

        <form method="post" action="{% url 'posts:post' post.id %}">
          {% csrf_token %}
          {{ comment_form.as_p }}
          <button type="submit">Add comment</button>
        </form>

        {% load mptt_tags %}
          {% recursetree comments %}
          <h5>{{ node.date_added }}</h5>
          <p>{{ node.user_comment }}</p>
              <form method="post" action="{% url 'posts:post' post.id %}">
              {% csrf_token %}
              {{ comment_form.as_p }}
              <input type="hidden" name="comment_id" value="{{ node.id }}">
              <button type="submit">Reply</button>
              </form>
          {% if not node.is_leaf_node %}
            <div style="padding-left: 20px">
            {{ children }}
            </div>
          {% endif %}
          {% endrecursetree %}


    {% endblock %}

urls.py urls.py

    from django.urls import path

    from . import views

    app_name = 'posts'
    urlpatterns = [
        path('posts/', views.posts, name='posts'),
        path('posts/<int:post_id>/', views.post, name='post'),
    ]

MPTT trees are great for getting a list of subnodes or node counts. MPTT树非常适合获取子节点列表或节点数。 They are costly for adding/inserting nodes and the cost increases linearly with the size of the three. 它们增加/插入节点的成本很高,并且成本随着三个节点的大小线性增加。 They are designed to fit tree data into relational databases. 它们旨在使树数据适合关系数据库。 Also, don't get fooled by "I'll have much more reads than writes". 另外,不要被“我的读写要多得多”所迷惑。 Ideally, most of the reads should hit a cache, not the database under it. 理想情况下,大多数读取应命中高速缓存,而不是高速缓存下的数据库。

Why not skip the relational database and go with a NoSQL database that can natively store trees? 为什么不跳过关系数据库,而选择可以原生存储树的NoSQL数据库呢? There are easy integrations for Django and pretty much every NoSQL database you can thing about. Django和几乎每个NoSQL数据库都可以轻松集成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM