Django之模板(Template)

Django模板系统

官方文档

每一个Web框架都需要一种很便利的方法用于动态生成HTML页面。 最常见的做法是使用模板。

模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插入静态部分。

说白了,模板层就是如何往HTML文件中填入动态内容的系统。

Django可以配置一个或多个模板引擎(语言),也可以不用引擎。

Django自带一个称为DTL(Django Template Language )的模板语言,以及另外一种流行的Jinja2语言(需要提前安装,pip install Jinja2)。

Django为加载和渲染模板定义了一套标准的API,与具体的后台无关。加载指的是,根据给定的模版名称找到的模板然后预处理,通常会将它编译好放在内存中。渲染则表示,使用Context数据对模板插值并返回生成的字符串。

DTL作为Django原生的模板系统,一直到Django1.8,都是唯一的内置模版系统,可能你对它有些意见,但是它仍然是一个优秀的模版库。如果没有特别重要的理由,需要选择另外一种模版系统的话,建议坚持使用DTL,特别是在编写可插拔的应用并打算发布其模板的时候。Django很多内部组件都使用了DTL,例如django.contrib.admin,如果你不想让它们罢工,或者花费大力气进行修改,不要放弃DTL。

 配置引擎

模板引擎通过settings中的TEMPLATES设置来配置。这是一个列表,与引擎一一对应,每个元素都是一个引擎配置字典。由startproject命令生成的settings.py会自定定义如下的值:

常用语法

只需要记两种特殊符号:

{% %}

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

变量

{{ 变量名 }}

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

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

例子:

tenplate_test.html
<body>
{#  变量相关用{{  }} #}
{{ s1 }}
{# helson 字符串#}
<hr>
{{ l }}
{#['jassin', 'lishi', 'dandan'] 列表 #}
{##}
<hr>
{{ d }}
{#{'name': 'jassin', 'age': 21}  字典#}
<hr>
{{ l2 }}
{#对象列表#}
{#[<app01.views.template_test.<locals>.Person object at 0x00000000048DD470>, #}
{# <app01.views.template_test.<locals>.Person object at 0x00000000048DD358>, #}
{# <app01.views.template_test.<locals>.Person object at 0x00000000048DD4E0>]#}


views.py
def template_test(request):
    s1 = "helson"
    l = ["jassin","lishi","dandan"]
    d = {"name":"jassin","age":21}

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

        def dream(self):
            return "{}的梦想是好好生活".format(self.name)

    jassin = Person("Jassin")
    lishi = Person("Lishi")
    dandan = Person("Dandan")

    l2 = [jassin,lishi,dandan]

    # return render(request, "template_test.html",{locals()})
    return render(request, "template_test.html",{"s1":s1,"l":l,"d":d,"l2":l2})


urls.py
    url(r'^template_test/$',views.template_test, name="template_test"),
参数

模板支持的写法

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

注意点;

Django模板语言  对象.方法就可以执行,不需要加括号

Filters过滤器

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

html页面
<body>
{#  变量相关用{{  }} #}
{{ s1 }}
{# helson 字符串#}
<hr>
{{ l }}
{{ l.1 }}
{#['jassin', 'lishi', 'dandan'] 列表 #}
{##}
<hr>
{{ d }}
{{ d.age }}
{#{'name': 'jassin', 'age': 21}  字典#}
<hr>
{{ l2 }}
{{ l2.0.name }}
{{ l2.0.dream }}
<hr>
{{ lili|default:"没有这个值" }}
{#没有这个值#}
{{ l|length }}
{# 3#}
{{ filesize|filesizeformat }}
{#1.2 KB#}
{{ s1|slice:"1:3" }}
{#el#}
<hr>
{{ now }}
{#Jan. 19, 2018, 4:37 p.m.#}
<hr>


views。py
def template_test(request):
    s1 = "helson"
    l = ["jassin","lishi","dandan"]
    d = {"name":"jassin","age":21}

    import datetime
    now = datetime.datetime.now()




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

        def dream(self):
            return "{}的梦想是好好生活".format(self.name)

    jassin = Person("Jassin")
    lishi = Person("Lishi")
    dandan = Person("Dandan")

    l2 = [jassin,lishi,dandan]

    # return render(request, "template_test.html",{locals()})
    return render(request, "template_test.html",{"s1":s1,"l":l,"d":d,"l2":l2,"filesize":1200,"now":now})
参数

default

{{ value|default: "nothing"}}  如果value值没传的话就显示nothing
{{ lili|default:"没有这个值" }}

length

返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.
l = ["jassin","lishi","dandan"] {{ l|length }} # 3

filesizeformat

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

例如:(自动转化)

"filesize":1200
{{ filesize|filesizeformat }}
# 1.2 KB

slice切片

s1 = "helson"
{{ s1|slice:"1:3" }}  # 左包含右不包含
# el

date格式化

{{ now|date:"Y-m-d  H:i:s" }}
2018-01-19 16:41:42

safe**

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

比如:

value = "<a href='#'>点我</a>"
{{ value|safe}}
{{ s2 }}
{#<a href='http://www.jianshu.com/'>点呀</a> 自动帮你转译成字符串#}

truncatechars

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

参数:截断的字符数

{{ s3 }}
风中的少年如今在他乡皎洁的月光寂静的晚上谁的思念伴我入梦乡。
{{ s3|truncatechars:6 }}  字符   风中的...
{{ s3|truncatewords:3 }}  单词(用于单词之间的空格)

自定义filter***

template_test.html
{% load app01_tags %}
{{ s1|replace:"o"}}



app01_tags.py
from django import template
register = template.Library()

# {{变量|filter_name:参数}}
# name 是给函数起名字,
@register.filter(name="replace")
def func(value,arg):
    return value.replace(arg,"666")
参数
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)

from django import template
register = template.Library()

# {{变量|filter_name:参数}}
# name 是给函数起名字,
@register.filter(name="replace")
def func(value,arg):
return value.replace(arg,"666")

使用自定义filter

{# 先导入我们自定义filter那个文件 #}
{% load app01_filters %}

{# 使用我们自定义的filter #}
{{ somevariable|cut:"0" }}
{{ d.name|addSB }}

# 将o替换成666
{% load app01_tags %} # 导入
{{ s1|replace:"o"}}
{#hels666n#}

Tags(跟逻辑相关)

for

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

for循环可用的一些参数:

 

for ... empty

l4没有
<ul> {% for name in l4 %} <li>{{ 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

定义一个中间变量

当l2.0.dream变量比较长的可以起个中间变量,别名
{% with l2.0.dream as dream %} {{ dream }} # 这里可以直接调用那个中间变量 {% endwith %}

 csrf_token********

这个标签用于跨站请求伪造保护。
在页面的form表单里面写上{% csrf_token %}

 

------------------------------------------------模板引擎--------------------------------

模板引擎

a. 基本使用

  {{ k1 }}

  if

  for

自定义函数

b.模板中自定义函数

  在已注册的app中创建一个名字叫 templatetags 文件夹

  在任意创建一个py文件

  创建名字叫register的Library类的对象

  定义函数

from django.template import Library
register = Library() 

   # 调用示例:{{"jassin"|func1:"jassin,lili"}}
   # 参数最多2
   # 可以做if的
                @register.filter
                def meikai(a1,a2):
                    n1,n2 = a2.split(',')
                    data = "我的名字叫:%s,我喜欢%s和%s" %(a1,n1,n2)
                    return data
   

   # 调用示例:{% func3 1 2 3 4 %}
   # 参数无限制
   # 无法做if条件
   @register.simple_tag
   def func3(a1,a2,a3,a4):
      resule = a1+a2+a3+a4
      return result
  使用
    {% load xl %}
      {{ "jassin"|meikai:"lishi,lili"}}
       {% func2 1 2 3 4 %}

# 关于自己建app
  注册app
  推荐:'app01.apps.App01Config'

 模板引擎示例:

{% load xl %}
<!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>
</head>
<body>
    <h1>{{ k1 }}</h1>
    <h1>{{ k1|upper }}</h1>    {# 使字母大写 #}
    <h1>{{ "jassin"|func1:"lishi,lili"}}</h1>
    <h1>{% func2 1 2 3 4 %}</h1>

    {% if "sudflexsdf"|func3 %}
        <h1>哇哈哈哈</h1>
    {% else %}
        <h1>娃哈哈</h1>
    {% endif %}

{#这也是能使字母大写的方法,但不是动态的#}
{#    {% if k1 == 'v1' %}#}
{#        <h1>V1</h1>#}
{#    {% endif %}#}



</body>
</html>
HTML
# templatetags文件
from
django.template import Library register = Library() def func1(a1,a2): n1,n2 = a2.split(',') data = "我的名字叫:%s,我喜欢%s和%s" %(a1,n1,n2) return data # 接收多个参数,但不能做if条件 @register.simple_tag def func2(a1,a2,a3,a4): result = a1+a2+a3+a4 return result # 只能接收2个参数,可以做if条件 @register.filter def func3(a1): if 'alex' in a1: return True return False @register.filter def func4(a1): if 'alex' in a1: return True return False
原文地址:https://www.cnblogs.com/jassin-du/p/8316646.html