利用Django模版生成树状结构实例代码


Posted in Python onMay 19, 2019

前言

我们经常会有这样的需求,比如评论功能,每个评论都有可能会有自己的子评论,如果在界面只展示成一列的话非常不美观,也不能体现出他们的层级关系。那么我们今天就来看看如何使用Django的模版来生成树状结构,以本站为例,效果如下图所示:

利用Django模版生成树状结构实例代码

那么我们要怎么实现呢?首先先看看评论实体的定义,如下所示:

class Comment(models.Model):
 body = models.TextField('正文', max_length=300)
 author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='作者', on_delete=models.CASCADE)
 article = models.ForeignKey(Article, verbose_name='文章', on_delete=models.CASCADE)
 parent_comment = models.ForeignKey('self', verbose_name="上级评论", blank=True, null=True, on_delete=models.CASCADE)

可以看到,有一个parent_comment字段,关联自己。这样就可以根据这个字段来生成层级关系。 为了方便我们使用,我们自定义了一个叫query的tag,也可以叫修饰器。定义tag的代码如下,tag的定义应该定义在app/templatetags目录下,这里py文件命名为blog_tags.py:

@register.simple_tag
def query(qs, **kwargs):
 """ template tag which allows queryset filtering. Usage:
   {% query books author=author as mybooks %}
   {% for book in mybooks %}
   ...
   {% endfor %}
 """
 return qs.filter(**kwargs)

接下来下面这段代码是树节点的模版代码。

{% load blog_tags %}
{% load comments_tags %}
 <div id="commentlist-container" class="comment-tab" style="display: block;">
    <ol class="commentlist">
     {% query article_comments parent_comment=None as parent_comments %}
     {% for comment_item in parent_comments %}
      {% with 0 as depth %}
       {% include "comments/tags/comment_item_tree.html" %}
      {% endwith %}
     {% endfor %}
    </ol>
   </div>

其中的{% query article_comments parent_comment=None as parent_comments %}的功能就是从评论中筛选出来是父级的评论。 comment_item_tree.html的实现也很简单:

{% load blog_tags %}
<li class="comment even thread-even depth-{{ depth }} parent" id="comment-{{ comment_item.pk }}"
 style="margin-left: {% widthratio depth 1 3 %}rem">
 <div id="div-comment-{{ comment_item.pk }}" class="comment-body">
  <div class="comment-meta commentmetadata">
   {{ comment_item.created_time }}
  </div>
  <p>{{ comment_item.body |escape|custom_markdown }}</p>
  <div class="reply"><a class="comment-reply-link"
        href="javascript:void(0)" rel="external nofollow" 
        onclick="do_reply({{ comment_item.pk }})"
        aria-label="回复给{{ comment_item.author.username }}">回复</a></div>
 </div>

</li><!-- #comment-## -->
{% query article_comments parent_comment=comment_item as cc_comments %}
{% for cc in cc_comments %}
 {% with comment_item=cc template_name="comments/tags/comment_item_tree.html" %}
  {% with depth=depth|add:1 %}
   {% include template_name %}
  {% endwith %}
 {% endwith %}
{% endfor %}

其中最主要的部分就是</li>标签后面那段。这里使用with和include配合来在每一次循环里面重复的引入comment_item_tree.html,并且每次引入时赋予当前的评论变量和depth(每层循环depth会+1)。然后在每个评论处使用style="margin-left: {% widthratio depth 1 3 %}rem"来实现缩进,这样就实现了树状显示。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python 文件重命名工具代码
Jul 26 Python
java直接调用python脚本的例子
Feb 16 Python
详细介绍Python的鸭子类型
Sep 12 Python
解决pip install xxx报错SyntaxError: invalid syntax的问题
Nov 30 Python
Python Excel处理库openpyxl使用详解
May 09 Python
python儿童学游戏编程知识点总结
Jun 03 Python
修改 CentOS 6.x 上默认Python的方法
Sep 06 Python
python修改FTP服务器上的文件名
Sep 11 Python
如何利用pygame实现简单的五子棋游戏
Dec 29 Python
解决pycharm下pyuic工具使用的问题
Apr 08 Python
python rolling regression. 使用 Python 实现滚动回归操作
Jun 08 Python
Python 机器学习工具包SKlearn的安装与使用
May 14 Python
使用Python3内置文档高效学习以及官方中文文档
May 19 #Python
python反编译学习之字节码详解
May 19 #Python
python从入门到精通 windows安装python图文教程
May 18 #Python
详解用Python实现自动化监控远程服务器
May 18 #Python
Python实现打砖块小游戏代码实例
May 18 #Python
如何在Python中实现goto语句的方法
May 18 #Python
OpenCV搞定腾讯滑块验证码的实现代码
May 18 #Python
You might like
咖啡历史、消费和行业趋势
2021/03/03 咖啡文化
PHP去除数组中重复的元素并按键名排序函数
2008/08/18 PHP
php 遍历显示文件夹下所有目录、所有文件的函数,没有分页的代码
2008/11/14 PHP
php smarty的预保留变量总结
2008/12/04 PHP
ie与session丢失(新窗口cookie丢失)实测及解决方案
2013/07/15 PHP
浅析PHP原理之变量(Variables inside PHP)
2013/08/09 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
PHP实现验证码校验功能
2017/11/16 PHP
PHP单例模式应用示例【多次连接数据库只实例化一次】
2018/12/18 PHP
基于jquery实现图片广告轮换效果代码
2011/07/07 Javascript
JavaScript打开word文档的实现代码(c#)
2012/04/16 Javascript
Bootstrap表单简单实现代码
2017/03/06 Javascript
十分钟带你快速了解React16新特性
2017/11/10 Javascript
JavaScript实现的简单Tab点击切换功能示例
2018/07/06 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
2018/08/16 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
vue前后分离调起微信支付
2019/07/29 Javascript
Vue 3自定义指令开发的相关总结
2021/01/29 Vue.js
Python中的条件判断语句基础学习教程
2016/02/07 Python
Python三级目录展示的实现方法
2016/09/28 Python
Pycharm技巧之代码跳转该如何回退
2017/07/16 Python
Python正确重载运算符的方法示例详解
2017/08/27 Python
Python实现的堆排序算法原理与用法实例分析
2017/11/22 Python
pandas通过字典生成dataframe的方法步骤
2019/07/23 Python
关于tensorflow的几种参数初始化方法小结
2020/01/04 Python
Python实现EM算法实例代码
2020/10/04 Python
CSS3模块的目前的状况分析
2010/02/24 HTML / CSS
Rosetta Stone官方网站:语言学习
2019/01/05 全球购物
销售代表求职自荐信
2013/10/01 职场文书
工商管理专业职业生涯规划
2014/01/01 职场文书
一年级家长会邀请函
2014/01/25 职场文书
副科竞争上岗演讲稿
2014/05/12 职场文书
2014年个人售房协议书
2014/10/30 职场文书
升学宴答谢词
2015/01/05 职场文书
2016年心理学教育培训学习心得体会
2016/01/12 职场文书
详解CSS中postion和opacity及cursor的特性
2022/08/14 HTML / CSS