• Django模板系统


    官方文档

    常用语法

    只需要记两种特殊符号:

    { { } } 和{ % % }

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

    变量

    { { 变量名 } }

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

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

    几个例子:

    view中代码:

    def template_test(request):
        l = [11, 22, 33]
        d = {"name": "alex"}
    
        class Person(object):
            def __init__(self, name, age):
                self.name = name
                self.age = age
    
            def dream(self):
                return "{} is dream...".format(self.name)
    
        Alex = Person(name="Alex", age=34)
        Egon = Person(name="Egon", age=9000)
        Eva_J = Person(name="Eva_J", age=18)
    
        person_list = [Alex, Egon, Eva_J]
        return render(request, "template_test.html",
    {"l": l, "d": d, "person_list": person_list})

     模板中支持的写法:

    {# 取l中的第一个参数 #}
    {{ l.0 }}
    {# 取字典中key的值 #}
    {{ d.name }}
    {# 取对象的name属性 #}
    {{ person_list.0.name }}
    {# .操作只能调用不带参数的方法 #}
    {{ person_list.0.dream }}

    Filters

    语法:{ { value|filte_name:参数} }

    default
    {{ value|default:"nothing"}}

    如果value值没传的话显示nothing

    length

    { { value|length} }

    ‘|’左右没有空格

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

    filesizeformat

    将值格式化为一个“人类可读的”文件尺寸

    {{value|filesizeformat}}

    如果value是123456789,输出将会是117.8MB

    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}}

    后端:

    from django.utils.safestring import mark_safe
    ss1 = mark_safe("<h1>我是h1</h1>")
    ss2 = mark_safe("<script>alert(123)</script>")

    truncatechars

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

    参数:截断的字符数

    {{value|truncatechars:9}}

    自定义

    必须做下面三件事:

    1. 必须在应用下新建一个名为templatetags的文件夹
    2. 在该文件夹下创建一个任意名的py文件
    3. 在该文件内必须先写下面两句话
    #文件内必须先写下面两句话
    from django import template
    resgiter = tmplate.Library()

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

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

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

    自定义filter代码文件摆放位置(名字必须是templateags的包):

    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 }}

    编写自定义标签
    @register.simple_tag(name='plus')
    def plus(a,b,c):
        return '%s-%s-%s'%(a,b,c)

     使用自定义标签

    {% plus xx 'egon' 'kevin' %}
    编写自定义inclusion_tag
    @register.inclusion_tag('login.html')
    def get_html(n):
        l = []
        for i in range(n):
            l.append('第%s项'%i)
        return {'l':l}

     使用自定义inclusion_tag

    <ul>
        {% for foo in l %}  <!--l = ['第0项','第1项','第2项'......]-->
            <li>{{ foo }}</li>
        {% endfor %}
    </ul>

     自定义标签 过滤器 inclusion_tag都是为了能够调用它返回相应的结果

     区别:

      自定义标签和过滤器返回的仅仅是数据而已

         而我的inclusion_tag返回的是一段html代码而已!!!

    Tags

    for

    <ul>
    {% for user in user_list %}
        <li>{{ user.name }}</li>
    {% endfor %}
    </ul>

    for循环可用的一些参数:

    VariableDescription
    forloop.counter 当前循环的索引值(从1开始)
    forloop.counter0 当前循环的索引值(从0开始)
    forloop.revcounter 当前循环的倒序索引值(从1开始)
    forloop.revcounter0 当前循环的倒序索引值(从0开始)
    forloop.first 当前循环是不是第一次循环(布尔值)
    forloop.last 当前循环是不是最后一次循环(布尔值)
    forloop.parentloop 本层循环的外层循环

    for ...empty

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

     if ,elif和else

    {% if user_list %}
      用户人数:{{ user_list|length }}
    {% elif black_list %}
      黑名单数:{{ black_list|length }}
    {% else %}
      没有用户
    {% endif %}

     当然也可以只有if和else

    {% if user_list|length > 5 %}
      七座豪华SUV
    {% else %}
        黄包车
    {% endif %}

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

     with

     定义一个中间变量

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

    csrf_token

    这个标签用于跨站请求伪造保护

    在页面的form表单里面写上{% csrf_token %}

     这个机制跟cookie,session机制原理差不都,主要是用来对数据安全性进行校验,
        举例:比如以前在网络安全还不是很发达的年代,有很多冒充银行等涉及到个人财产的钓鱼网站(将自己的网站做的跟银行转账网站一样)你在钓鱼网站上输入账号密码转账给谁谁时,钓鱼网站也会将数据发给真正的银行后台处理地址,唯一不同的在于,钓鱼网站展示给你的转账给目标账号起始只是一个伪标签,它的内部隐藏了一个写有钓鱼者期望转账的银行账户,这样就造成给受骗者一种虽然转账成功但是钱转入的是他人账户。。。相似的欺骗手段还有很多
        为了能够识别出提交给我的数据就是从我的网站转发过来的,这里就用到了csrf_token,你只需要在你需要提交数据的html内容体内加上{% csrf_token %}这一段内容,Django会自动的在用户访问到相应页面时给这个页面一长串的验证码,当再次提交时Django也会自动帮你进行验证,如果标识码不正确,会返回给客户端一个403表示请求数据有错误来防止第三方钓鱼网站的干扰
    View Code

    注释

    {# ....#}

    注意事项

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

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

    2.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的值。

    母板

    <!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>Title</title>
      {% block page-css %}
      
      {% endblock %}
    </head>
    <body>
    
    <h1>这是母板的标题</h1>
    
    {% block page-main %}
    
    {% endblock %}
    <h1>母板底部内容</h1>
    {% block page-js %}
    
    {% endblock %}
    </body>
    </html>

    注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。

    继承母板

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

    {% extends 'layouts.html' %}

    块(block)

      通过在母板中使用{% block xxx%}来定义“块”。

      在子页面中通过定义母板中的block名来对应替换母板中相应的内容。

    {% block page-main %}
      <p>世情薄</p>
      <p>人情恶</p>
      <p>雨送黄昏花易落</p>
    {% endblock %}

    组件

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

    {% include 'navbar.html' %}

    静态文件相关

    {% 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!" />
  • 相关阅读:
    CDR
    xshell鼠标文本设置
    .NET多线程学习之龟兔赛跑
    js传“+”或“&”到后台变空值的问题
    Java递归读取文件夹下所有文档
    破解Myeclipse10找不到Commonplugins文件夹
    Java下载文件
    根据给定日期判断上一旬的开始结束日期
    查看Tomcat内存并调整Tomcat内存
    Could not parse mapping document from input stream
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10718400.html
Copyright © 2020-2023  润新知