【问题标题】:django-mptt tree model returns empty children in template using recursetreedjango-mptt 树模型使用递归树返回模板中的空子节点
【发布时间】:2021-10-25 18:03:32
【问题描述】:

我正在使用 Django 3.2 和 django-mppt 0.13.4

这是我的(简化的)模型:

/path/to/myapp/models.py

class Comment(MPTTModel, MyTimestampedModel):

    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True,  related_name='children')

    content = models.TextField(default='')
    markdown_content = models.TextField(default='')

    attachment = models.ImageField()     


    class MPTTMeta:
        order_insertion_by = ['created_at']

    class Meta:
        permissions = [('can_moderate_comments', 'Can moderate comments'),
                       ('can_attach_file', 'Can attach file'),]


class Commentable(models.Model, Foo):
    accept_comments = models.BooleanField(default=True, blank=True)    
    comments = GenericRelation(Comment)
    
    # ... other fields


class Article(Commentable, FooBar):
    pass

/path/to/myapp/views.py

class ArticleDetailView(DetailView):
    model = Article    

    def get_context_data(self, **kwargs):
       context = super(ArticleDetailView, self).get_context_data(**kwargs)
             
       article = self.get_object()
       # ....

       context['comments'] = article.comments.all() 

来自the mptt documentation

<ul class="root">
    {% recursetree nodes %}
        <li>
            {{ node.name }}
            {% if not node.is_leaf_node %}
                <ul class="children">
                    {{ children }}
                </ul>
            {% endif %}
        </li>
    {% endrecursetree %}
</ul>

/path/to/myapp/templates/myapp/article_detail.html

       {% recursetree comments %}
           <li>
                 {{ node.markdown_content }}
                 {% if not node.is_leaf_node %}
                    {{node.get_descendant_count}} Replies
                    <ul class="children">
                    {{ children }} 
                    </ul>
                 {% endif %}
           </li>            
        {% endrecursetree %}  

我将三个 cmets 添加到数据库中(通过shell 命令),具有以下层级关系:

Comment 1 (id=1)
  Reply To Comment 1 (id=3)
    Reply To Reply to Comment 1 (id=4)
Comment 2 (id=2)

当我在命令提示符下键入以下内容时:

Comment.objects.filter(id=1).get_children() 
=> 1

Comment.objects.filter(id=1).get_descendent_count()
=> 2

但是(现在只关注第一条评论),在我的模板中,虽然 node.get_descendant_count 变量与直接从数据库获得的匹配,但子项在模板中是一个空集 - 而当直接访问数据库时,返回正确数量的(直接)子级。

为什么模板没有正确返回评论的子级 - 我该如何解决这个问题?

【问题讨论】:

  • "comment1:2 回复,comment3:1 回复,comment4,comment2"。这是正确的结果吗?如果正确,则 mptt 中没有问题。刚刚在我的本地 Django/mptt 上得到了正确的结果。
  • @Devstorm21 不,这不是正确的结果。正确的结果是我在控制台打印出来的问题。请注意,最好参考get_children().countget_descendant_count(),因为回复的数量太不明确了。
  • 你看我的回答了吗?
  • @DanielKaminski 是的。你读过我的问题吗?您似乎忽略了我正在关注文档但它仍然无法正常工作的事实(我给出了示例),您只是写了一个答案告诉我它可以正常工作。
  • 更新了答案。我确信结果是正确的。对吗?

标签: django django-mptt


【解决方案1】:

无需修复它,因为它可以正常工作。请仔细阅读以下来自https://django-mptt.readthedocs.io/en/latest/templates.html的注意事项

注意特殊变量nodechildren。这些很神奇 当您在 recursetree 标记内时插入到您的上下文中。

node 是您的 MPTT 模型的一个实例。

children :该变量保存为子级渲染的 HTML 节点。

得到了mptt_tags.py的评论。

遍历树中的节点,并渲染包含的块 对于每个节点。 此标记将递归地将子代渲染到模板变量{{ children }} 中。 只需要一个数据库查询(children 为整棵树缓存)

我得到了以下正确的结果。

<li>
    comment1
      2 Replies
  <ul class="children">
    <li>comment3
        1 Replies
        <ul class="children">
            <li>
            comment4
            </li>            
        </ul>           
    </li>            
  </ul>           
</li>

【讨论】: