zoukankan      html  css  js  c++  java
  • 第五章 Django框架——模板层Templates

    第五章 Django框架——模板层Templates

    一、MTV模式与MVC模式

    二、模板语法之变量

    三、模板语法之过滤器filter

    四、模板语法之tags(与逻辑相关的)

    五、模板之母版继承之block与extends

    六、模板之母版导入之include(组件)

    七、自定义simpletag

    一、MTV模式与MVC模式

    MVC模式

    MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等优点。

    Django的MTV模式

    Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。

    Django框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架。

    • Model(模型):负责业务对象与数据库的对象(ORM)
    • Template(模版):负责如何把页面展示给用户
    • View(视图):负责业务逻辑,并在适当的时候调用Model和Template
    • 此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

    二、模板语法之变量

    只需要记两种特殊符号:

    {{ filter }}和 {% tag %}

    变量相关的用{{}},逻辑相关的用{%%}。

    1.变量

    语法:

    {{ 变量名 }}

    构成:

    变量名由字母数字和下划线组成。

    点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。

    基本使用:

    注意:

    如果页面输入一个没有赋值的变量,页面上将不会显示它

    方法:

    A)列表操作

     ①按索引去列表值

    B)字典操作

     ①按key取值

    C)对象操作

     ①直接调用对象(也可以用__str__方法控制打印格式)

      结果:

     ②获取对象属性

     ③获取对象方法(只能调用不带参数的方法,因为没有办法加括号)

    三、模板语法之过滤器filter

    语法:

    {{ value|filter_name:参数 }}

    切记:

    '|'左右没有空格没有空格没有空格

    方法:

    ①default  如果value值没传的话就显示default的内容

    # 如果value值没传的话就显示nothing
    {{ value|default: "nothing"}}

    ②length  返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

    <p>{{ name|length }}</p>

     ③filesizeformat  将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB''4.1 MB''102 bytes', 等等)。

    {{ value|filesizeformat }}

     

     

     ④slice  切片 可以切列表,字符串

    {{value|slice:"2:-1"}}

     ⑤date  格式化时间

    {{ value|date:"Y-m-d H:i:s"}}

     ⑥safe 告诉浏览器我这段代码是完全安全的

     Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。

    比如:

    value = "<a href='#'>点我</a>"

    {{ value|safe}}

     ⑦truncatechars  如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾

    参数:截断的字符数

    {{ value|truncatechars:9}}

     ⑧trunctewords  将字符串转换为省略表达式

    { 'This is a pen' | truncatewords:2 }}返回
    This is ...

     ⑨其他(了解即可)

    过滤器 描述 示例
    upper 以大写方式输出 {{ user.name | upper }}
    add 给value加上一个数值 {{ user.age | add:”5” }}
    addslashes 单引号加上转义号  
    capfirst 第一个字母大写 {{ ‘good’| capfirst }} 返回”Good”
    center 输出指定长度的字符串,把变量居中 {{ “abcd”| center:”50” }}
    cut 删除指定字符串 {{ “You are not a Englishman” | cut:”not” }}
    date 格式化日期  
    default 如果值不存在,则使用默认值代替 {{ value | default:”(N/A)” }}
    default_if_none 如果值为None, 则使用默认值代替  
    dictsort 按某字段排序,变量必须是一个dictionary {% for moment in moments | dictsort:”id” %}
    dictsortreversed 按某字段倒序排序,变量必须是dictionary  
    divisibleby 判断是否可以被数字整除
    {{ 224 | divisibleby:2 }}  返回 True
    escape 按HTML转义,比如将”<”转换为”&lt”  
    filesizeformat 增加数字的可读性,转换结果为13KB,89MB,3Bytes等
    {{ 1024 | filesizeformat }} 返回 1.0KB
    first 返回列表的第1个元素,变量必须是一个列表  
    floatformat 转换为指定精度的小数,默认保留1位小数 {{ 3.1415926 | floatformat:3 }} 返回 3.142  四舍五入
    get_digit 从个位数开始截取指定位置的数字 {{ 123456 | get_digit:’1’}}
    join 用指定分隔符连接列表 {{ [‘abc’,’45’] | join:’*’ }} 返回 abc*45
    length 返回列表中元素的个数或字符串长度  
    length_is 检查列表,字符串长度是否符合指定的值 {{ ‘hello’| length_is:’3’ }}
    linebreaks 用<p>或<br>标签包裹变量 {{ “Hi David”|linebreaks }} 返回<p>Hi</p><p>David</p>
    linebreaksbr 用<br/>标签代替换行符  
    linenumbers 为变量中的每一行加上行号  
    ljust 输出指定长度的字符串,变量左对齐 {{‘ab’|ljust:5}}返回 ‘ab   ’
    lower 字符串变小写  
    make_list 将字符串转换为列表  
    pluralize 根据数字确定是否输出英文复数符号  
    random 返回列表的随机一项  
    removetags 删除字符串中指定的HTML标记 {{value | removetags: “h1 h2”}}
    rjust 输出指定长度的字符串,变量右对齐  
    slice 切片操作, 返回列表 {{[3,9,1] | slice:’:2’}} 返回 [3,9]
    {{ 'asdikfjhihgie' | slice:':5' }} 返回 ‘asdik’
    slugify 在字符串中留下减号和下划线,其它符号删除,空格用减号替换
    {{ '5-2=3and5 2=3' | slugify }} 返回 5-23and5-23
    stringformat 字符串格式化,语法同python  
    time 返回日期的时间部分  
    timesince 以“到现在为止过了多长时间”显示时间变量 结果可能为 45days, 3 hours
    timeuntil 以“从现在开始到时间变量”还有多长时间显示时间变量  
    title 每个单词首字母大写  
    truncatewords 将字符串转换为省略表达方式
    {{ 'This is a pen' | truncatewords:2 }}返回
    This is ...
    truncatewords_html 同上,但保留其中的HTML标签
    {{ '<p>This is a pen</p>' | truncatewords:2 }}返回
    <p>This is ...</p>
    urlencode 将字符串中的特殊字符转换为url兼容表达方式 {{ ‘http://www.aaa.com/foo?a=b&b=c’ | urlencode}}
    urlize 将变量字符串中的url由纯文本变为链接  
    wordcount 返回变量字符串中的单词数  
    yesno 将布尔变量转换为字符串yes, no 或maybe
    {{ True | yesno }}
    {{ False | yesno }}
    {{ None | yesno }}
    返回 
    yes
    no 
    maybe

     

    自定义filter:

    自定义过滤器只是带有一个或两个参数的Python函数:

    • 变量(输入)的值 - -不一定是一个字符串
    • 参数的值 - 这可以有一个默认值,或完全省略

    例如,在过滤器{{var | foo:“bar”}}中,过滤器foo将传递变量var和参数“bar”

    自定义filter代码文件摆放位置:

    app01/
        __init__.py
        models.py
        templatetags/  # 在app01下面新建一个package package
            __init__.py
            app01_filters.py  # 建一个存放自定义filter的文件
        views.py

    编写自定义filter:

    from django import template
    register = template.Library()
    
    
    @register.filter(name="cut")
    def cut(value, arg):
        return value.replace(arg, "")
    
    
    @register.filter(name="addSB")
    def add_sb(value):
        return "{} SB".format(value)

    使用自定义filter:

    {# 先导入我们自定义filter那个文件 #}
    {% load app01_filters %}
    
    {# 使用我们自定义的filter #}
    {{ somevariable|cut:"0" }}
    {{ d.name|addSB }}

     

    四、模板语法之tags(与逻辑相关的)

    1.for

    语法:

    ①for循环的基本用法:
    {% for i in name_list %}
    {{ i }}
    {% endfor %}

    {% for i in name_list %}
    {{ i }}
    {% empty %}
    空空如也
    {% endfor %}


    ②for循环可用的属性:

    forloop代表当前的for循环
    forloop.counter    forloop.counter表示当前循环的执行次数的整数计数器。该计数器从1开始,即第一次循环时{{% forloop.counter %}}的值为1

    forloop.counter0  forloop.counter0 计数从0开始,第一次循环其值为0

    forloop.revcounter    值是一个整数,表示循环中剩余的元素数量。第一次循环时, for-loop.revcounter 的值是序列中要遍历的元素总数。最后一次循环时, forloop.revcounter 的值为 1 

    forloop.revcounter0  索引是基于零的。第一次循环时, for-loop.revcounter0 的值是序列中元素数量减去一。最后一次循环时, forloop.revcounter0 的值为 0 

    forloop.first     是个bool值,第一次循环时为true
    forloop.last     是个bool值,最后一次循环时为true
    forloop.parentloop    forloop.parentloop 引用父级循环的 forloop 对象

    举例:

    {% for country in countries %}
    <table>
    {% for city in country.city_list %}
    <tr>
    <td>Country #{{ forloop.parentloop.counter }}</td>
    <td>City #{{ forloop.counter }}</td>
    <td>{{ city }}</td>
    </tr>
    {% endfor %}
    </table>

    {% endfor %}

    ③for...empty...

    <ul>
    {% for user in user_list %}
        <li>{{ user.name }}</li>
    {% empty %}
        <li>空空如也</li>
    {% endfor %}
    </ul>

    2.if,elif,else

    语法:

    {% if a > b %}
    {% endif %}

    {% if a > b %}
    {% else %}
    {% endif %}

    {% if a > b %}
    {% elif %}
    {% else %}
    {% endif %}

    if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

    3.with

    定义一个中间变量

    {% with total=business.employees.count %}
        {{ total }} employee{{ total|pluralize }}
    {% endwith %}

    自定义tags

    自定义tags代码文件摆放位置:

    编写自定义tags:

    使用自定义tags:

     

    小技巧:

    static引入

    注意:

    ①filter可以用在if等语句后,simple_tag不可以

    {% if num|filter_multi:30 > 100 %}
        {{ num|filter_multi:30 }}
    {% endif %}

    ②注意事项

    Django的模板语言不支持连续判断,即不支持以下写法:

    {% if a > b > c %}
    ...
    {% endif %}

    ③Django的模板语言中属性的优先级大于方法

    def xx(request):
        d = {"a": 1, "b": 2, "c": 3, "items": "100"}
        return render(request, "xx.html", {"data": d})

    如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:

    {{ data.items }}

    默认会取d的items key的值。

    五、模板之母版继承之block与extends

    为什么要有母版(why):

     可以将每个页面共有的部分定义为母版使用,多个页面公用的部分提取出来,放在一个 母版 里面,其他的页面只需要 继承 母版就可以了。

    1.具体使用的步骤:
    ① 把公用的HTML部分提取出来,放到base.html文件中
    ②在base.html中,通过定义block,把每个页面不同的部分区分出来

    {% block page-main %}
    ...
    {% endblock%}


    ③在具体的页面中,先继承母版

    {% extends 'xxx.html' %}

    ④然后block名去指定替换母版中相应的位置

    2.母版的继承

     在子页面中在页面最上方使用下面的语法来继承母板。

    {% extends 'layouts.html' %}

    3.母版的导入

    语法:{% include '模版名称' %}

     如:{% include 'adv.html' %}

    使用母版继承的注意事项:

    ①{% extends 'base.html' %} --> 母版文件:base.html要加引号
    ②{% extends 'base.html' %}必须放在子页面的第一行!!!
    ③可以在base.html中定义很多block,通常我们会额外定义page-css和page-js两个块
    ④view.py相应的函数中返回的是对应的子页面文件不是base.html

    ④view.py相应的函数中返回的是对应的子页面文件不是base.html

    ④view.py相应的函数中返回的是对应的子页面文件不是base.html

    重要的事情说三遍

    静态文件相关:

    用法一:{% static "xxx.css" %}

    引用图片

    {% load static %}
    <img src="{% static "images/hi.jpg" %}" alt="Hi!" />

    引入Js

    {% load static %}
    <script src="{% static "mytest.js" %}"></script>

    某个文件多处被用到可以存为一个变量

    % load static %}
    {% static "images/hi.jpg" as myphoto %}
    <img src="{{ myphoto }}"></img>

    用法二 :使用get_static_prefix

    {% load static %}
    <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
    {% load static %}
    {% get_static_prefix as STATIC_PREFIX %}
    
    <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
    <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

    六、模板之母版导入之include(组件)

     可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。

    {% include 'navbar.html' %}

    七、自定义simpletag

    ①先去setting里面把app名字配置上
    ②再app目录下创建一个templatetags模块
    ③写py文件(my_test.py)

    from django import template
    register=template.Library()
    @register.inclusion_tag('test.html')
    def my_inclusion(n):
      data=[]
      for i in range(n):
      data.append('第%s行'%i)
      return {'data':data}

    ④写test.html页面

    <ul>
    {% for choice in data %}
    <li>{{ choice }}</li>
    {% endfor %}
    </ul>

    ⑤{% load my_test %}
    ⑥{% my_inclusion 10 %} 它会返回html的页面

    inclusion_tag

    多用于返回html代码片段

    示例:

    templatetags/my_inclusion.py

    from django import template
    
    register = template.Library()
    
    
    @register.inclusion_tag('result.html')
    def show_results(n):
        n = 1 if n < 1 else int(n)
        data = ["第{}项".format(i) for i in range(1, n+1)]
        return {"data": data}
    View Code

    templates/snippets/result.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>inclusion_tag test</title>
    </head>
    <body>
    
    {% load inclusion_tag_test %}
    
    {% show_results 10 %}
    </body>
    </html>
    View Code
  • 相关阅读:
    详解单例模式
    Spring整合Mybatis案例,献给初学的朋友
    Java反射学习总结
    IDEA JSP项目构建及学习心得
    SQL Server数据库表锁定原理以及如何解除表的锁定
    MySQL锁定机制简介
    Cassandra简介
    Linux机器上实现程序自动部署以及更新
    服务器时间同步平台化
    内存查看平台化
  • 原文地址:https://www.cnblogs.com/neymargoal/p/9599749.html
Copyright © 2011-2022 走看看