繁体   English   中英

Django线程评论系统

[英]Django Threaded Commenting System

(对不起我的英语)

我正在学习Python和Django。 现在,我的挑战是开发线程化通用注释系统。 有两种模型,“发布”和“评论”。

-帖子可以发表评论。

-评论可以评论。 (环形/螺纹)

-不应是系统中的n + 1查询问题。 (无论有多少评论,都不应增加查询数量)

我当前的模型是这样的:

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")

我的模特对吗? 而且我如何才能获得帖子的所有注释(带有层次结构),而不会出现n + 1个查询问题?

注意:我知道mttp和其他模块,但是我想学习这个系统。


编辑:我运行“ Post.objects.all().prefetch_related("child").get(pk=1) ”命令,这给了我帖子及其子注释。 但是,当我想获取子命令的子命令时,新查询正在运行。 我可以将命令更改为...prefetch_related("child__child__child...")...然后仍然针对子-父子关系的每个深度运行一个新查询。 有谁有解决此问题的想法吗?

如果您希望通过单个查询获取帖子的所有评论,那么最好将每个评论链接到相关的帖子。 您可以使用单独的链接来指示父注释。

基本上:

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)

由于使用中间表,因此创建该关联的许多很多需要花费一些额外的工作 如果您想要一个纯粹的一对多,那么您需要在Comment上使用ForeignKey ,但是仅限于prefetch_related而不是select_related ,这会涉及额外的数据库命中。

这样也更好,因为您没有未类型化的外键引用(您的PostitiveIntegerField )。

然后,您需要将注释排列成树形结构,但这超出了您的问题范围。

暂无
暂无

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

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