Django template syntax and use

Django template syntax and use

django template language description (taken from official documents) Links

"""
Django模板语言
Django的模板语言旨在在功能和易用性之间取得平衡。它让那些习惯使用HTML的人感到舒服。
如果您对其他基于文本的模板语言(如Smarty 或Jinja2)有过接触,那么您应该对Django的模板感到宾至如归。

哲学
如果您有编程背景,或者习惯于将编程代码直接混合到HTML中的语言,那么您需要记住,
Django模板系统不仅仅是嵌入到HTML中的Python。这是一种设计,模板系统用于表达,而不是程序逻辑。

Django模板系统提供的标签功能类似于一些编程结构 如 if,布尔,for标签,循环标签等 - 但这些标签不是简单地作为相应的Python代码执行,
模板系统不会执行任意Python表达式。默认情况下,仅支持下面列出的标记,过滤器和语法(您可以根据需要将自己的扩展添加到模板语言中)。

哲学
为什么使用基于文本的模板而不是基于XML的模板(如Zope的TAL)?我们希望Django的模板语言不仅可用于XML / HTML模板。
在World Online,我们将其用于电子邮件,JavaScript和CSV。您可以将模板语言用于任何基于文本的格式。

哦,还有一件事:让人类编辑XML是虐待狂!
"""

What is a template?

模板只是一个文本文件。它可以生成任何基于文本的格式(HTML,XML,CSV等)。
模板包含变量,这些变量在评估模板时将替换为值,而变量则包含控制模板逻辑的标记。
只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板。

Note Templates statement

模板语句的注释
{#{{ '10'|add_str:'5 '}}#}  
{#注释内容#}    

{} {} Variable Variable

  • Variables: {{}} The syntax is: Riga brackets to render variable the value of the variable, the variable name consists of alphanumeric characters and underscores.
  • Code
#views 文件函数
def template_test(request):
    name = '钢蛋'
    age = 18
    hobby = ['唱', '跳', 'rap', '篮球']
    lis = []
    st = ''
    dic = {
        'name': '铁蛋',
        'age': 16,
        'hobby': hobby,
        'keys': 'xxxxx'
    }
    dic_2 = {}
    return render(request,'template_test.html',
 {'name':name_p,'age':age,'hobby':hobby,'lis':lis,'st':st,'dic':dic,'dic_2':dic_2})

# 模板文件html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>郭楷丰</title>
</head>
<body>
{{ 啦啦啦啦啦 }}
<p>
    {{ name }}
</p>
<p>
   {{ age }}
</p>
<p>
    {{ hobby }}
</p>
<p>
    {{ lis }}
</p>
<p>
    {{ st }}
</p>
<p>
    {{ dic }}
</p>
<p>
    {{ dic_2 }}
</p>
</body>
</html>
  • Browser results:

img

  • Summary: {{}} to fill to be rendered variable, written specification, as separated on both sides in parentheses {} {} variables, parameter passing backend does not display the page
    img

img

Dot (.) Has a special meaning in the template language, corresponding to the acquired attribute of the object.

  • Sample Code Index .key. Property. Method
#views 文件函数
def template_test(request):
    lis = [1, 2, 3,4,5]
    dic = {"name": "黑蛋"}

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age

        def dream(self):
            return " 我 is {} age {}岁...".format(self.name,self.age)

    gangdan = Person(name="钢蛋", age=18)
    goudan = Person(name="狗蛋", age=17)
    tiedan  = Person(name="铁蛋", age=16)

    person_list = [gangdan, goudan, tiedan]
    return render(request, "template_test.html", {"lis": lis, "dic": dic, "person_list": person_list})

# 模板文件html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>郭楷丰</title>
</head>
<boby>
    <p>{{ lis.0 }}</p>   <!--取l中的第一个参数-->
    <p>{{ dic.name }}</p><!--取字典中key的值-->
    <p>{{ person_list.0.name }}</p><!--取对象的name属性-->
    <p>{{ person_list.0.dream }}</p><!--.操作只能调用不带参数的方法-->
</boby>
</html>
  • summary:
#注:当模板系统遇到一个(.)时,会按照如下的顺序去查询:
1. 在字典中查询
2. 属性或者方法
3. 数字索引   # 索引不能为负数

img

img

%}% {Tag Tags represent operating logic associated

  • Code examples
{% for foo in lis %}
<!--for循环-->
    {% if  %}
    <!--if判断-->
    {% elif %}
    <!--elif判断-->
    {% endif %}
    <!--if闭合符-->
    {% else %}
    <!--else判断不成立执行-->
{% endfor %}
<!--for循环闭合符-->

<!--应用 模板html代码-->
<form action="" method="post">
    <label for="inputEmail3" class="col-sm-2 control-label">书名: </label>
    <div class="col-sm-8">
        <input type="text" name="book_name" class="form-control" value="{{ edit_obj.title }}">
        <select name="pub_id" id="" class="btn btn-default  btn-sm">
            {% for foo in publishers %}
            {% if foo == edit_obj.pub %}
            <option selected value="{{ foo.pk }}"> {{ foo.name }}</option>
            {% else %}
            <option value="{{ foo.pk }}"> {{ foo.name }}</option>
            {% endif %}
            {% endfor %}
        </select>
    </div>
    <div class="text-center text-danger">{{ error }}</div>
    <div class="col-sm-offset-2 col-sm-10">
        <button type="submit" class="btn btn-default">提交</button>
    </div>
</form>

<!--应用 python逻辑代码 #views 文件函数-->
def edit_book(request):
    error = ''
    pk = request.GET.get('pk')
    edit_obj = models.Book.objects.filter(id=pk)
    if not edit_obj:
        return HttpResponse('要编辑的数据不存在')
    if request.method == 'POST':
        book_name = request.POST.get('book_name')
        if not book_name.strip():
            error = "书名不能为空"
        pub_id = request.POST.get('pub_id')
        if edit_obj[0].title == book_name and edit_obj[0].pub_id == int(pub_id):
            error = "未作修改"
        if not error:
            obj = edit_obj[0]
            obj.title = book_name
            obj.pub_id = int(pub_id)
            obj.save()
            return redirect('/book_list/')
    publishers = models.Publisher.objects.all()
    return render(request,'edit_book.html',{'edit_obj':edit_obj[0],'publishers':publishers,'error':error})
  • Implementation of the results

img

img

  • if statement supports and, or, ==,>, <,! =, <=,> =, in, not in, is, is not to judge.

  • js, python, template language of logic judgment

    #python
    10>5>1  =》   10>5  and 5>1   true 
    
    #js
    10>5>1  =》   10>5  =》 true   =》   1>1  false
    
    #模板中  
    不支持连续连续判断,也不支持算数运算(过滤器)
  • Precautions

  • Django template language does not support continuous judgment, does not support the following wording:

{% if a > b > c %}
...
{% endif %}
#不支持算数运算 + - * /
  • In Django template language attribute priority is greater than the method
def xx(request):
    d = {"a": 1, "b": 2, "c": 3, "items": "100"}
    return render(request, "xx.html", {"data": d})
  • As above, when we use the render method to render a page, pass a dictionary d key items and there is a default d.items () method, this time in the template language:
{{ data.items }}   默认会取d的items key的值。

The for loop parameters are available:

Variable Description
forloop.counter Loop current index value (starting at 1)
forloop.counter0 Loop current index value (zero)
forloop.revcounter Reverse current loop index (1 to end)
forloop.revcounter0 Reverse circulating current index value (0 to end)
forloop.first The current cycle is not the first cycle (Boolean value)
forloop.last The current cycle is not the last cycle (Boolean value)
forloop.parentloop This layer of outer loop cycles
  • for ... empty

#for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
{% for person in person_list %}
    <p>{{ person.name }}</p>
{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

Filters filter

  • Shows the results used to modify the variable Syntax: {{value | filter_name: Parameter}} ':' about no space no space is no space

  • Set division divisible divisibleby: Parameter

img

with use

  • The definition of an intermediate variable (from the individual name takes effect only internally with)
#写法一
{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

#写法二
{% with business.employees.count as total %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

img

default system default

{{ value|default:"nothing"}}
如果value值没传的话就显示nothing
注:TEMPLATES的OPTIONS可以增加一个选项:string_if_invalid:'找不到',可以替代default的的作用。
(在配置文件settings.py设置)
  • Variable does not pass configuration setting parameters displayed value

img

  • Results page

img

filesizeformat file size humane display

  • Value formatted as a "human readable" file size (e.g. '13 KB ',' 4.1 MB ',' 102 bytes', etc.), for example:
{{ value|filesizeformat }}
如果 value 是 123456789,输出将会是 117.7 MB

add "加"

  • Add to the variable parameters, try to turn the default string int type, can not turn on the splice
{{ value|add:"2" }}
value是数字4,则输出结果为6

{{ value|add:"hello" }}
value是数字666,则输出结果为666hello

{{ first|add:second }}
如果first是 [1,.2,3] ,second是 [4,5,6] ,那输出结果是 [1,2,3,4,5,6] 

lower lowercase

{{ value|lower }}

upper uppercase

{{ value|upper}}

title title

{{ value|title }}

ljust Left

"{{ value|ljust:"10" }}"

rjust right-aligned

"{{ value|rjust:"10" }}"

center center

"{{ value|center:"15" }}"

length length

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

slice slice

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

first take the first element

{{ value|first }}

last taken last element

{{ value|last }}

join using string concatenation list

  • str.join with the python (list)
{{ value|join:" // " }}

cut to remove all the given value of the same variable character string

  • If value is 'i love you', then the output 'iloveyou'.
{{ value|cut:' ' }}

truncatechars accordance character truncation ... also count

  • If the string of characters is more than a specified number of characters, it will be truncated. Truncated strings will be translated sequence ellipsis ( "...") at the end
#参数:截断的字符数
{{ value|truncatechars:9}}

truncatewords 按照单词进行截断, 只针对英文(...)不计数,中文按字计算

date date format

#后端
import datetime
def mul(request):
    value = datetime.datetime.now()
    return render(request, 'mul.html',{'value':value})

#模板语句
{{ value|date:"Y-m-d H:i:s"}}   #显示格式 年-月-日 时:分:秒


#后端
import datetime
def mul(request):
    now = datetime.datetime.now()
    return render(request, 'mul.html',{'now':now})

#模板直接使用变量
{{ now }}  #显示格式 June 19,2019,22:00 p.m.

#时间格式和默认值一起使用
{{ obj.next_date|date:"Y-m-d"|default:"暂无" }}
  • Results page

img

img

img

  • Character can be formatted output: Click to view
  • Change profile settings display style (permanent solution)
#settings.py文件设置
USE_L10N = False  #更换为False

DATETIME_FORMAT = 'Y-m-d H:i:s' #添加

#也可以日期与时间分开设置  根据自己的需求设置
DATE_FORMAT = 'Y-m-d'   
TIME_FORMAT = 'H:i:s'

img

safe to prevent xss attack role unescaping

  • Simple to understand xss attacks
    XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,
故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
    XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。
这种类型的漏洞由于被骇客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,
骇客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。
  • xss attacks Process

img

The main role of safe

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

#自定过滤器代码
@register.filter
def show(url,name):
    return "<a href = '{}'>{}</a>".format(url,name)
  • Page display

img

  • The filter function applied is_safe = True release escapes
#自定过滤器代码
@register.filter(is_safe = True)
def show(url,name):
    return "<a href = '{}'>{}</a>".format(url,name)
  • Results page
    img
  • Templates statement released plus safe escape
#模板语句
{% load my_tags %}
{{ 'https://www.baidu.com/'|show:'百度'|safe }}
  • Results page
    img

  • The module may be introduced to achieve this effect

img

img

Custom filter

  • When ordinary built-in filter, can not achieve our development needs, we can customize the filter function to achieve
自定义过滤器是只能带有一个或两个参数的Python函数:
变量(输入)的值 - -不一定是一个字符串
参数的值 - 这可以有一个默认值,或完全省略
例如,在过滤器{{var | foo:“bar”}}中,过滤器foo将传递变量var和参数“bar”。
自定义filter代码文件摆放位置:
app01/
    __init__.py
    models.py
    templatetags/  # 在app01下面新建一个package package
        __init__.py
        app01_filters.py  # 建一个存放自定义filter的py文件
    views.py

Custom filter process

  • 1 Create a file named in the App templatetags Python packages
#注意 
在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag

(模块名只能是templatetags)
  • 2 Create py file in python, the file name can be customized, such as: (my_tags.py)
  • 3 written in py file:
from django import template

register = template.Library()  #固定写法,不可改变
  • 4 + write function decorator
@register.filter  #过滤器
def add_str(value, arg):  # 最多有两个
    return '{}-{}'.format(value, arg)
  • 5 write page code my_tags.py created before using import from html file defines simple_tag and filter in
{% load my_tags %}   #先导入我们自定义那个文件 my_tags
{{ name|add_str:age }}   #参数只能是两个,一个参数是变量name ,一个是参数是后面的那个参数age
  • Results of the

img

  • Custom filter multiplier multioly

#过滤器函数
@register.filter
def multiply1(value,arg):
    return value * arg
    
#模板语句
{% load my_tags %}
<p>{{ 6|multiply1:'6' }}</p>
<p>{{ 6|multiply1:6 }}</p>
<p>{{ '10'|multiply1:5 }}</p>
  • Results of the

img

img

  • Custom filters division divider

#过滤器函数
@register.filter
def division(value,arg):
    return value / arg

#模板语句
{% load my_tags %}
<p>{{ 6|division:6 }}</p>
<p>{{ 6|division:1 }}</p>
  • Results of the

img

  • Add custom filters divider

#过滤器函数
@register.filter
def add(value,arg):
    return value + arg   #可以这样写,但是转换不了会报错 int(value) + int(arg)

#模板语句
{% load my_tags %}
<p>{{ 6|add:6 }}</p>
<p>{{ 6|add:0 }}</p>

<p>{{ '钢蛋g'|add:18 }}</p>
  • Results of the

img

img

  • Custom filters subtraction subtractor

#过滤器函数
@register.filter
def add(value,arg):
    return value - arg

#模板语句
{% load my_tags %}
<p>{{ 6|add:6 }}</p>
<p>{{ 6|add:0 }}</p>
  • Results of the

img

Custom label simpletag

  • With a custom filter difference, more acceptable parameters, using a reference tag {%} {%
与自定义filter类似(也是在python包的templatetags文件下,创建此标签),只不过接收更灵活的参数。

#simple_tag  代码
@register.simple_tag(name="plus")
def plus(a, b, c):
    return "{} + {} + {}".format(a, b, c)

#使用simple tag  自定义标签 
{% load app01_demo %}
{# simple tag #}
{% plus "1" "2" "abc" %}
    
    
#例子  标签代码
@register.simple_tag
def join_str(*args, **kwargs):
    return '{} - {} '.format('*'.join(args), '$'.join(kwargs.values()))

# 模板
{% load my_tags %}
{% join_str '1' '2' '钢蛋' k1='3' k2='4' %}    
  • Implementation of the results

img

Custom label inclusion_tag

  • Html for multiple return code (dynamic variables tab)

img

img

  • Create a python package under the app file

img

  • The package file name must be templatetags

img

  • Create any .py files inside templatetags

img

  • Write function

img

  • html page code

    #分页显示代码
    <nav aria-label="Page navigation">
      <ul class="pagination">
        <li>
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
        {% for i in num %}
            <li><a href="#">{{ i }}</a></li>
        {% endfor %}
        <li>
          <a href="#" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
    
    
    #页面1
    {% load my_tags %}
    {% page 5 %}
    
    #页面2
    {% load my_tags %}
    {% page 1 %}
    
  • display effect

img

img

img

  • to sum up:

自定义过滤器 filter 只能接受两个参数 调用的时候使用 {{ filter }}

自定义标签  simpletag  与自定义过滤器区别,可以接受更多参数,使用标签引用{{%  %}
                                            
自定义标签 inclusion_tag  多用于返回html代码片段,使用标签引用{{% %}                                   

CSRF protection csrf_token

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

img

img

Static related files

#作用 在配置文件找到静态文件别名,与文件地址进行拼接,这样别名改了,也不会影响,静态文件的导入

{% 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>


{% load static %}
 <link rel="stylesheet" href="{% static '/plugins/bootstrap-3.3.7/css/bootstrap.css' %}">
 <link rel="stylesheet" href="{% static '/css/dsb.css' %}">
{% static '/plugins/bootstrap-3.3.7/css/bootstrap.css' %}  

{% get_static_prefix %}   # 获取别名
  • Gets the aliases profile

img

img

Master and inheritance

What is a master?

普通的HTML页面 母版页用于处理html页面相同部分内容,避免出现冗余代码,减少重复html页面的编写,提高代码复用性,方便代码修改.

Inheritance wording

#在子页面中在页面最上方使用下面的语法来继承母板。
{% extends '母版文件名.html' %}

block block

通过在母板中使用{% block  xxx %}来定义"块"。
在子页面中通过定义母板中的block名来对应替换母板中相应的内容。

#定义block
{% block 块名 %}
{% endblock  %} #还可以{{% endblock 块名 %}}来关闭标签,更加清新

#使用block
{% block 块名 %}

    #自己的内容   

{% endblock  %}

#母版内容和自己内容都使用
{% block 块名 %}

    #自己的内容   
    {% block.super %}

{% endblock  %}

Alternatively subpages master block block

img
img

  • Precautions
注意的点:

1. {% extends 'base.html' %} 写在第一行   前面不要有内容 有内容会显示
2. {% extends 'base.html' %}  'base.html' 加上引号   不然当做变量去查找
3. 把要显示的内容写在block块中
4. 定义多个block块,定义 css  js 块

Package

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

#示列  单独建一个html  page
<nav aria-label="Page navigation">
  <ul class="pagination">
    <li>
      <a href="#" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>
    {% for i in num %}
        <li><a href="#">{{ i }}</a></li>
    {% endfor %}
    <li>
      <a href="#" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>
</nav>

#别的页面 引用
{% include 'page.html' %}

Guess you like

Origin www.cnblogs.com/TMesh/p/11832794.html
Recommended