简体   繁体   English

Django线程评论系统

[英]Django Threaded Commenting System

(and sorry for my english) (对不起我的英语)

I am learning Python and Django. 我正在学习Python和Django。 Now, my challange is developing threaded generic comment system. 现在,我的挑战是开发线程化通用注释系统。 There is two models, Post and Comment. 有两种模型,“发布”和“评论”。

-Post can be commented. -帖子可以发表评论。

-Comment can be commented. -评论可以评论。 (endless/threaded) (环形/螺纹)

-Should not be a n+1 query problem in system. -不应是系统中的n + 1查询问题。 (No matter how many comments, should not increase the number of queries) (无论有多少评论,都不应增加查询数量)

My current models are like this: 我当前的模型是这样的:

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

    child = generic.GenericRelation(
        'Comment',
        content_type_field='parent_content_type',
        object_id_field='parent_object_id'
    )

class Comment(models.Model):
    content = models.TextField()

    child = generic.GenericRelation(
        'self',
        content_type_field='parent_content_type',
        object_id_field='parent_object_id'
    )

    parent_content_type = models.ForeignKey(ContentType)
    parent_object_id = models.PositiveIntegerField()
    parent = generic.GenericForeignKey(
        "parent_content_type", "parent_object_id")

Are my models right? 我的模特对吗? And how can i get all comment (with hierarchy) of post, without n+1 query problem? 而且我如何才能获得帖子的所有注释(带有层次结构),而不会出现n + 1个查询问题?

Note: I know mttp and other modules but I want to learn this system. 注意:我知道mttp和其他模块,但是我想学习这个系统。


Edit: I run " Post.objects.all().prefetch_related("child").get(pk=1) " command and this gave me post and its child comment. 编辑:我运行“ Post.objects.all().prefetch_related("child").get(pk=1) ”命令,这给了我帖子及其子注释。 But when I wanna get child command of child command a new query is running. 但是,当我想获取子命令的子命令时,新查询正在运行。 I can change command to ...prefetch_related("child__child__child...")... then still a new query running for every depth of child-parent relationship. 我可以将命令更改为...prefetch_related("child__child__child...")...然后仍然针对子-父子关系的每个深度运行一个新查询。 Is there anyone who has idea about resolve this problem? 有谁有解决此问题的想法吗?

If you want to get all comments on a post with a single query then it would be good to have every comment link to the asssociated post. 如果您希望通过单个查询获取帖子的所有评论,那么最好将每个评论链接到相关的帖子。 You can use a separate link to indicate the parent comment. 您可以使用单独的链接来指示父注释。

Basically: 基本上:

class Post(models.Model):
    ...
    comments = models.ManyToManyField('Comment')
    # link to all comments, even children of comments

class Comment(models.Model):
    ...
    child_comments = models.ManyToManyField('Comment')
    # You may find it easier to organise these into a tree 
    # if you use a parent_comment ForeignKey. That way the
    # top level comments have no parent and can be easily spotted.

Post.objects.all().select_related('comments').get(pk=1)

The many to many in this takes a little extra work to create the association, as it uses an intermediate table. 由于使用中间表,因此创建该关联的许多很多需要花费一些额外的工作 If you want a pure one to many then you need a ForeignKey on the Comment but then you are restricted to a prefetch_related instead of a select_related , which then involves an extra database hit. 如果您想要一个纯粹的一对多,那么您需要在Comment上使用ForeignKey ,但是仅限于prefetch_related而不是select_related ,这会涉及额外的数据库命中。

This is also better in that you do not have an untyped foreign key reference (your PostitiveIntegerField ). 这样也更好,因为您没有未类型化的外键引用(您的PostitiveIntegerField )。

You then need to arrange the comments into a tree structure, but that is outside the scope of your question. 然后,您需要将注释排列成树形结构,但这超出了您的问题范围。

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

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