Django学习之十三:提高页面开发效率减少冗余的模板系统

目录

  • Django 模板

    • 模板语法

      • 逻辑语法
      • 函数式过滤器
      • 内置filter
      • 功能tag
      • 注释
      • 内置tag
      • 导入三方tag and filter(load)
      • 过滤器和功能tag的区别
      • 自定义tag和filter
    • 上下文数据
    • 模板间关系
      • 继承关系
      • 包含关系
      • inclusion_tag关系
      • 小结

Django 模板

模板按照我的理解,就是让html中内容不固定,让html内容已后端的方式动态起来(虽然前端mvvm框架也也开始有模板概念,所以广义说模板概念不限于后端)。但是html基础的内容还是是固定的。模板通过类编程的模板语法,可以将html模板中的动态内容,通过后端程序的计算传入核心数据,最后通过模板语法得到一个完整的html。模板的构造核心就是:模板语法和上下文数据(渲染引擎的全局数据和后端代码传入的数据);模板的驱动就是模板引擎(如Jinja2,django内置的DTL)。模板语法的数据来自于上下文数据,使得模板可以动态的生成html内容,关键让类似内容的构造更加高效,如for循环渲染列表。模板语法还提供模板与模板间存在关系:继承关系和包含关系。模板间的关系时的开发网页减少大量的冗余内容。
后端使用模板,多用于开发访问量较小的后台管理系统。

模板语法

模版文件中使用的variables会被上下文字典中的对应的key的值所替代。
模版文件中使用的tags会被引擎执行一段相应的逻辑。

逻辑语法

  • {% if condition %} {% else %} 条件
  • {% for %} {% endfor%} 迭代

函数式过滤器

  • 说明: filter是用于转变 variable 和 tag‘s arguments 的
  • 例如: {{ django|title }} 其上下文 {‘django‘: ‘the web framework‘}
  • 渲染后:‘The Web Framework‘
  • filter参数:有些filter是可以传入参数的,参数传入方式是filter:argument;
  • 例如: {{ datetime|date:"Y-m-d" }}

内置filter

内置filter: 参见官档索引

功能tag

  • 语法: {% tag %}
  • tag用法: 不同tag有自己的处理逻辑,包括用户自定义的tag,并且tag可以接受参数,有些tag有开始和结束tag对。
  • {% csrf_token %} 无参数
  • {% cycle ‘odd‘ ‘even‘ %} 有参数
  • {% if user.is_authenticated %} Hello, {{ user.username }}. {% endif %} 有开始和结束tag对的。
  • 说明:tag有内置,也可自定义。

注释

  • 语法:{# this won‘t be rendered #}
  • 作用:就是注释,不会被渲染。
  • 多行注释利用tag: {% comment %} 多行注释内容 {% endcomment %}
  • 说明: 为什么不用html的注释,因为模版语言不止用于html文本,其它文本也可以,所以在模版语言这一层来进行注释才行。注意,注释不能嵌套。

内置tag

内置tag:参见官档索引

导入三方tag and filter(load)

{% load static %} 加载static app中templatetags目录下的static文件中定义的tag。
load同时也会导入tag和filter

过滤器和功能tag的区别

Tags的功能比filter要复杂的多,因为tag几乎可以做任何事情,包括最重要的渲染模版inclusion_tag。而filter主要是对数据进行处理。

自定义tag和filter

  1. 前提:最常见是自定义的tag是在对应的app目录下的创建的,所以要将app注册到settings的installed_apps列表中。
  2. 在app目录下创建templatetags目录,名字必须固定,这个是默认查找加载指定自定义tag和filter文件的地方,并在目录创建__init__.py文件。(是django默认的finder查找逻辑限制了这个名字)
  3. 创建py文件,自定义tag就放在文件中。文件名一定要小心,不要和其它app注册的冲突了。自定义filter和tag,如:
# my_tags.py
from django import template

register = template.Library()  # register变量名固定

@register.filter  # 自定义filter
def multi_tag(v1, v2):
    return v1 * v2

@register.simple_tag  # 自定义simple tag
def tag_add(v1, v2):
    return v1 + v2
  1. 自定义好自己的tags和filters,重要的一步就是将他们扩展使用到template引擎中,让他们生效就要使用{% load %} tag.
  2. 在模板文件中添加load标签后,需要重启服务。这点很关键啊!还有load后面的自定义tag保存的文件,不用引号,直接load后面跟文件名就行了
  3. 在模版中使用自定义tag和filter。模版间继承关系,是不会继承{% load %} 标签的,所以每个模版中要使用自定义的tag和filter都需要再次{% load %}一次。

上下文数据

  • 语法: {{ variable }}
  • 用法: My first name is {{ first_name }}. My last name is {{ last_name }}.
  • 非全局变量,需要提供的上下文字典(或者叫环境或者叫作用域):{‘first_name‘: ‘John‘, ‘last_name‘: ‘Doe‘}
  • 通过render后产生的结果:My first name is John. My last name is ‘Doe‘.
  • 如果变量指向的也是一个字典:那么使用dotted可以访问了字典中的值:{{ my_dict.key }} {{ my_object.attribute }} {{ my_list.0 }}

    全局数据

    内置:官档

  • request对象自动传入

    传入数据

  • render(‘inde.html‘, {已字典结构传入})

模板间关系

继承关系

通过{% extends ‘父模板.hmtl‘ %}‘

包含关系

通过{% include ‘插入的模板.html‘ %} , 说明插入的模板可以使用数据

inclusion_tag关系

inclusion_tag 通过自定义tag形式,tag绑定了一个模板,tag函数处理逻辑放回一个上下文字典供绑定的模板渲染。这种也相当于是模板的包含关系,只不过是通过一个自定义的inclusion_tag进行封装。且让插座与插头对接更为明确,就是提供给tag提供参数,参数就是对接的规范了。由于是tag的形式,tag函数代码可以访问后台的所有数据。

inclusion_tag 示例详解

? ?? ?下面代码将一个模版通过使用自定义的类型为inclusion tag即进行渲染使用:
? ?? ?这个自定义tag是怎么做到的呢?
? ?? ?首先,我们利用这个tag的场景是:多个url页面都要用到相同的页面布局内容。如:博客系统中的个人站点的用户文章列表,标签列表,公告;这些对于这个用户的站点内容都是一样的。这些共同的东西要怎么才能重复利用呢?对于学习了template继承知识的同学,可能想到的是使用继承关系既可以了。继承是没错,但是相同部分的内容,要提供给模版语言的数据还是要给予的,不同的是这些数据在各自的视图view函数中,要去重复的获取数据这些重复的获取数据的代码,在这些视图之间都是一样的。虽然模版得到了继承,但是模版要用到的数据还是造成了重复代码。要解决这个问题方式一:可以将获取数据的代码,封装到一个函数代码块中,这样能解决重复问题。这是利用基于模版的继承为主要思想的思路,因为模版必须继承才行。
? ?? ?上面提到的模版继承思路,有一个局限性就是耦合度太高,必须继承模版。有没有什么方法不用继承模版就可以实现相同页面块的即插即用(继承方式无法即插即用)。django的一个自定义tag类型,给我们提供了一种即插即用的思路,这种思路是基于模版语言的tag对应一个python函数逻辑的思想。只需要自定义一个tag,tag就可以在任何的模版中插入使用。tag要做的就是返回一个渲染了的在前面提到的重复页面就行了。(这个就类似与include内置tag功能的一样,不同的是,include的页面是死的页面;而这里自定义的tag是可以利用模版语言结合上下文数据,动态的渲染出这个即插即用的页面)。这个指定tag就是django的inclusion tags。
inlucsion tags 的使用需要准备两个东西:一个即插即用的template,另一个就是渲染模版的上下文context data数据了。这个数据就是我们第一种思想中提到的要通过一个封装函数获取的数据。其实参数就是通过被插入的主模版能够给我们提供的数据了。即插即用,解耦的思想很棒!下面过一个列子来实践这个即插即用的思想。

友情提醒一句:利用这个思想,首先是目的和使用场景,前端页面要重复使用有且并且要重复的页面的上下文数据获取较多比较麻烦且重复

开始示例:

  1. 模版stuff_list.html:

{# 公告 #}
<div class="panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">公告</h3>
    </div>
    <div class="panel-body">
        <ul class="panel-list" type="none">
            <li><span>用户别名: {{ user_obj.username }}</span></li>
            <li><span>园龄: {{ age_days }} 天</span></li>
            <li><span>随笔数: {{ user_obj.article_set.count }} 篇</span></li>
        </ul>
    </div>
</div>

{#随笔分类#}
<div class="panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">随笔分类</h3>
    </div>

    <div class="list-group">
        {% for item in article_category_queryset %}
            <a href="" class="list-group-item">{{ item.category__title }} ({{ item.count }})</a>
        {% endfor %}
    </div>
</div>

{#标签#}
<div class="panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">我的标签</h3>
    </div>

    <div class="list-group">
        {% for item in article_tag_queryset %}
            <a href="" class="list-group-item">{{ item.title }} ({{ item.count }})</a>
        {% endfor %}
    </div>
</div>

{#归档#}
<div class="panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">随笔归档</h3>
    </div>

    <div class="list-group">
        {% for item in article_archive_queryset %}
            <a href="" class="list-group-item">{{ item.y_m }} ({{ item.count }})</a>
        {% endfor %}
    </div>
</div>
  1. 自定义的tag文件my_tags_filters.py:

重复获取的上下问数据就在该文件中函数中实现,返回一个上下文数据字典。在利用渲染装饰器来装饰这个函数,装饰器函数要带入要渲染的模版文件。相当于就是装饰器给我们做渲染模版作用,我们的自定义函数来获取查询数据,返回渲染需要的上下文数据就行。

from django import template
from myblog import models
from django.utils import timezone
from django.db.models import Count

register = template.Library()

@register.inclusion_tag('myblog/stuff_list.html')  # 绑定我们的模板了
def stuff_list(user_obj):  # 参数需要一个,这里就是用户对象
    # 计算园龄 以天为单位
    curr_time = timezone.now()
    create_time = user_obj.create_time
    interval_timedelta = curr_time - create_time
    age_days = interval_timedelta.days

    user_articles = models.Article.objects.filter(user=user_obj)

    # 分类
    article_category_queryset = user_articles.values('category__pk').annotate(
        count=Count('pk')).values('category__title', 'count')

    # 标签
    # article_tag_queryset = user_articles.values('tag__pk').annotate(count=Count('pk')).values('tag__title', 'count')  这个计算出来是一个{'None': 6} 把None做了一个分类,下面分组方式就是一个[]的queryset。两种看来还是不一样。
    article_tag_queryset = models.Tag.objects.filter(blog=user_obj.blog).values('pk').annotate(
        count=Count('article__pk')).values('title', 'count')
    print(article_tag_queryset)  ###

    article_archive_queryset = user_articles.extra(select={'y_m': "date_format(create_time, '%%Y-%%m')"}).values(
        'y_m').annotate(count=Count('pk')).values('y_m', 'count')
    print(article_archive_queryset)  ###

    # 这就是即插即用模版的上下文数据;通过一个user_obj参数我们就得到了要渲染到绑定模板中的上下文数据了。
    return {'user_obj': user_obj,
            'age_days': age_days,
            'article_category_queryset': article_category_queryset,
            'article_tag_queryset': article_tag_queryset,
            'article_archive_queryset': article_archive_queryset,}
  1. 使用我们的inclusion_tag了,将my_tags_filters.py 放入到app目录下的templatetags目录下,然后再要使用的模板中进行{% load my_tags_filters %} 就可以了。然后使用tag {% stuff_list site_user %} 注意要传递我们的参数。

小结

  1. 从模板关系可以发散出:其实继承是非常好的内容重用减少冗余的设计,同时包含关系,也可以说是可插拔模式,插入即用,还可复用。包含关系多是用在画面构建方面,如设计图,html模板,画作等。
  2. 什么时候继承,什么时候包含:继承是框架,包含是插拔插件,包含是对继承的补充。继承局限更强,包含可跨继承。比如说,一个父模板,所有的子模版都是在继承父类的基础上修改覆盖。而包含可以在多个父模板中使用,突破了必须在一个父模板下的限制,但是包含不是随便插入,是类似插座和插头的概念,被插入模板需要提供给插入模板相关数据的。。
  3. 金字塔结构:通过模板引擎解析模板语法,根据传入上下文环境渲染出动态内容。模板语法。传入数据。
    tag和filter。模板关系。全局参数和传入参数。
    内置tag_filter和自定义tag_filter,tag功能强于filter。继承,include,inclusion_tag。request/auth。

原文地址:https://www.cnblogs.com/ZJiQi/p/10739600.html

时间: 2024-07-30 18:37:33

Django学习之十三:提高页面开发效率减少冗余的模板系统的相关文章

转:常用的几个提高iOS开发效率的开源类库及工具

常用的几个提高iOS开发效率的开源类库及工具 iOS开发者 : 开发几个常用的开源类库及下载地址: 算上这个连接:http://wenku.baidu.com/view/bbeb0091dd88d0d233d46a00.html 1.json json编码解码2.GTMBase64 base64编码解码3.TouchXML xml解析4.SFHFKeychainUtils 安全保存用户密码到keychain中 5.MBProgressHUD 很棒的一个加载等待特效框架6.ASIHTTPReque

提高你开发效率的十五个 Visual Studio 使用技巧

提高你开发效率的十五个 Visual Studio 使用技巧 相信做开发的没有不重视效率的.开发C#的都知道,我们很依赖VS,或者说,我们很感谢VS.能够对一个IDE产生依赖,说明这个IDE确实 有它的独特之处.无容置疑,VS是一个非常强大的IDE,它支持多语言编辑.支持C#,VB,C/C++,HTML......它拥有强大的调试编译功能.它让我们不用去记住那些安装,环境变量设置,服务器设置,编译的繁琐过程.高度集成化.凡事有利有弊,在敏捷开发盛行的时代,VS是否值得我们使用是 无容置疑的.但是

iOS开发——实用篇&amp;提高iOS开发效率的方法和工具

提高iOS开发效率的方法和工具 介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的IDE,在这里我主要介绍Xcode中提升开发效率的方法. 1.善用快捷键 快捷键是开发中必不可少的,当你善于使用快捷键的时候,十指在键盘上飞舞,那画面太美,我不敢想象. 常用快捷键操作 2.常用代码片段 开发中有一些常用的代码,可以放到代码片段中,然后下次你就可以使用快捷

提高eclipse使用效率(二) 提高Android开发效率的小技巧

2013-09-04 22:49:33cnblogs.com-sw926-点击数:214 XML文件的代码提示 adt中也有xml文件的代码提示,为了让提示来的更加猛烈,我们还要设置一下 打开eclipse - Window - Preferences,在右边的目录树中切换到XML - XML Files - Editor - Content Assist,是不是很熟悉,没错,就是Content Assist 接下来就简单了,延迟设为50ms,提示字母把能填的都填上去,设置完之后可以试一下.输入

使用注释提高iOS开发效率

文章目录 新手在开始参与一个开发项目的时候,会把大部分的时间耗费在阅读项目的需求文档.开发文档和代码,一篇好的需求文档和开发文档会帮助新手很快的理解项目的目标和进度,而新手对于代码的阅读会先从代码的注释开始.拥有良好注释的代码可以省去团队其他的开发者好多时间,不至于让其他参与者去一行一行的阅读代码,去不断地加断点查看代码地跳转逻辑,接下来我们就谈谈iOS开发中使用的一些注释. #pragma mark 确切地说,这是Xcode编译器特定得编译命令,它的作用就是在代码地编辑器中,将顶部的方法函数弹

itoo-快捷部署脚本--提高部署开发效率

 本次是第一次使用批处理文件来作为批量操作的工具,代替了人工的手动的复制,粘贴的方式,使用脚本实现了项目的启动.自动化部署,打开项目根目录.等等,提高了开发和调试的效率. 说明: 当前版本:1.0.0 作    者:李社河 ========================================== 使用说明: 1.直接运行Start__Me.bat即可 注意事项: 1.请在使用本脚本前,配置JBOSS_HOME和PROJ_HOME环境变量 (1)变量名:JBOSS_HOME    

提高iOS开发效率的方法和工具

IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的IDE,在这里我主要介绍Xcode中提升开发效率的方法. 1.善用快捷键 快捷键是开发中必不可少的,当你善于使用快捷键的时候,十指在键盘上飞舞,那画面太美,我不敢想象. 常用快捷键操作 2.常用代码片段 开发中有一些常用的代码,可以放到代码片段中,然后下次你就可以使用快捷方法来使用这些代码了,给大家看下我的Xcode中部分代码片段: 偷懒小技巧 3.Xcode插件 我想插件是Xcode必不

华为云 DAS,大幅提高数据库开发效率

华为云数据管理服务(Data Admin Service,简称DAS),是一款专业的简化数据库管理工具,提供优质的可视化操作界面,大幅提高工作效率,让数据管理变得安全简单.主要包含以下功能:1.SQL 窗口管理DAS 提供了类似 Excel 的表格方式编辑数据,让不懂 SQL 查询语言的用户也能无障碍增删.改查表数据以及统计分析.SQL 窗口提供 SQL 格式化.SQL 智能提示.SQL执行计划.SQL模板等功能.目前,DAS 新支持常用SQL保存功能,方便开发人员查找和复用. DAS常用 SQ

&lt;转&gt;提高iOS开发效率的方法和工具

介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的IDE,在这里我主要介绍Xcode中提升开发效率的方法. 1.善用快捷键 快捷键是开发中必不可少的,当你善于使用快捷键的时候,十指在键盘上飞舞,那画面太美,我不敢想象. 常用快捷键操作 2.常用代码片段 开发中有一些常用的代码,可以放到代码片段中,然后下次你就可以使用快捷方法来使用这些代码了,给大家看下