Django目录:https://blog.csdn.net/qq_41106844/article/details/105554082
Django模板语言介绍
官方描述
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是虐待狂!
什么是模板
模板只是一个文本文件。它可以生成任何基于文本的格式(HTML,XML,CSV等)。
模板包含变量,这些变量在评估模板时将替换为值,而变量则包含控制模板逻辑的标记。
只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板。
变量{{ }}
创建一个新的app
![20155953-da019957424d7967.png](https://i-blog.csdnimg.cn/blog_migrate/e12092e42554b6e4341746bae0a1a29b.png)
补上视图函数,分发路由表,路由表
one_exa.app05/views.py
----------------------
from django.shortcuts import render
def index(request):
name = '张三'
age = 20
hobby = ['唱', '跳', 'rap', '篮球']
dic = {
'name': '李四',
'age': 20,
'hobby': ['唱歌', '跳舞', '看书']
}
return render(request,'mb.html',\
{'name':name,'age':age,'hobby':hobby,'dic':dic})
one_exa.app05.urls.py
---------------------
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'mb/', views.index),
]
one_exa.one_exa.urls.py
---------
from django.urls import re_path,include
urlpatterns = [
re_path(r'^Journal/', include("app01.urls")),
re_path(r'^echarts/', include("app02.urls",namespace='visible')),
re_path(r'^fxjx/', include("app03.urls",namespace='booktest')),
re_path(r'^app04/', include("app04.urls")),
re_path(r'^app05/', include("app05.urls"))
]
然后我们来创建一个html文件:
one_exa.templates.mb.html
-------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板操作</title>
</head>
<body>
{{ 哈哈哈 }}
<p>
{{ name }}
</p>
<p>
{{ age }}
</p>
<p>
{{ hobby }}
</p>
<div>
<p>{{ dic.name }}</p>
<p>{{ dic.age }}</p>
<p>{{ dic.hobby }}</p>
</div>
</body>
</html>
运行,查看页面:
![20155953-9dc372e3c57ee5d6.png](https://i-blog.csdnimg.cn/blog_migrate/5cfbb03688f325f9d569afa408e4988b.png)
![20155953-23bce9293ee6cae5.png](https://i-blog.csdnimg.cn/blog_migrate/e651b4b2dfee54f5739a358e2d662deb.png)
运行结果和jinja2模板一样。
{{ }}里填要渲染的变量,规范写法,两边用括号隔开,后端没有传参的页面不显示。
例如 {{ name }}。
点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。
例如{{ dic.name }}
注:当模板系统遇到一个(.)时,会按照如下的顺序去查询:
- 在字典中查询
- 属性或者方法
- 数字索引(索引不能是负数)
注释{# #}
{#{{ name }}#}
{#注释内容#}
Tags标签 {% %}
Tags 标签用来表示逻辑相关的操作。控制语句与循环语句就是最典型的逻辑操作。
控制语句if
控制语句if支持:
1.and or
2.==、<=、>=、<、>、!=
3.is、in、not is、not in
不支持连续判断(3>2>1),还有算术运算符(可以用过滤器实现)
one_exa.templates.mb.html
-------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板操作</title>
</head>
<body>
{% if age > 18 %}
<p>张三是成人了</p>
{% endif %}
</body>
</html>
![20155953-c1ad9e3328326d2d.png](https://i-blog.csdnimg.cn/blog_migrate/75f8bfc3b0efe9628aeca39461a5cacb.png)
循环语句for
for循环有一些参数,可以直接在HTML中通过{{forloop}}调用:
Variable | Description |
---|---|
forloop.counter | 当前循环的索引值(从1开始) |
forloop.counter0 | 当前循环的索引值(从0开始) |
forloop.revcounter | 当前循环的倒序索引值(到1结束) |
forloop.revcounter0 | 当前循环的倒序索引值(到0结束) |
forloop.first | 当前循环是不是第一次循环(布尔值) |
forloop.last | 当前循环是不是最后一次循环(布尔值) |
forloop.parentloop | 本层循环的外层循环 |
one_exa.templates.mb.html
-------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板操作</title>
</head>
<body>
{% for key,value in dic.items %}
{#字典的items也是可以用的。#}
<p> {{ key }} -- {{ value }}</p>
{% endfor %}
</body>
</html>
![20155953-a1795110a6692875.png](https://i-blog.csdnimg.cn/blog_migrate/cc529051bf8fab2800b759c252a81d0b.png)
for 标签带有一个可选的{% empty %} 从句
one_exa.templates.mb.html
-------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板操作</title>
</head>
<body>
{{ li }}
{% for i in li %}
<p> {{ i }}</p>
{% empty %}
{#当dic为空时,执行下面的语句#}
<p>Li is empty.</p>
{% endfor %}
</body>
</html>
![20155953-3697068bc013d932.png](https://i-blog.csdnimg.cn/blog_migrate/c3941af3782d252923741ce25a2a7519.png)
Filters 过滤器
在Django的模板语言中,通过使用 过滤器 来改变变量的显示;Django的模板语言中提供了大约六十个内置过滤器。
过滤器规则
- 过滤器的语法: {{ value|filter_name:参数 }}
- 使用管道符"|"来应用过滤器。
过滤器注意事项
- 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
- 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
- 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
- '|'左右没有空格
常用过滤器
filter_name | 功能 | 例子 |
---|---|---|
add | 给value加上一个数值 | {{ user.age 丨add:”5” }} |
capfirst | 第一个字母大写 | {{ value丨 capfirst }} |
cut | 移除与给出参数相同的字符串 | {{ “han” 丨cut:”an” }} |
center | 字符串居中 | {{ value丨 center:"15"}} |
default | 变量设置默认值 | {{ value丨default:"nothing"}} |
date | 日期时间格式化 | {{ value丨date:"Y-m-d H:i:s"}} |
dictsort | 按某字段排序,变量必须是一个dict | {% for l in ls丨dictsort:”id” %} |
dictsortreversed | 按某字段倒序排序,变量必须是dict | {% for l in ls丨dictsortreversed:”id” %} |
divisibleby | 判断是否可以被数字整除 | {{ 224 丨divisibleby:2 }} |
filesizeformat | 将值格式化为一个文件大小 | {{ 1024 丨filesizeformat }} |
first | 返回列表的第1个元素,变量必须是一个列表 | {{value丨first}} |
floatformat | 转换为指定精度的小数,默认保留1位 | {{ 3.1415丨 floatformat:2}} |
get_digit | 从个位数开始截取指定位置的数字 | {{ 1234丨 get_digit:’1’}} |
join | 按给定参数字符拼接 | {{ value丨join:"+" }} |
length | 返回字符串和列表变量的长度 | {{ value丨length }} |
ljust | 输出指定长度的字符串,变量左对齐 | {{‘ab’丨ljust:5}}返回 ‘ab ’ |
lower | 将变量全部转换成小写 | {{ value丨lower}} |
make_list | 将字符串转换为列表 | {{ value丨make_list}} |
random | 返回列表的随机一项 | {{ value丨random}} |
slice | 切片 | {{ value丨slice:"2:-1" }} |
safe | 对HTML标签和JS等语法标签进行自动转义 | {{ value丨safe}} |
truncatechars | 截取字符串 | {{ value丨truncatechars:9}} |
truncatewords | 截取单词数 | {{ value丨truncatewords:3}} |
upper | 将变量全部转换成大写 | {{ value丨upper}} |
然后我们举几个常用的过滤器的例子:
- add
<p>{{ dic.age }}<p>
<p>{{ dic.age | add:"5" }}<p>
![20155953-39829d3b9ee5facd.png](https://i-blog.csdnimg.cn/blog_migrate/59285667f1dd25d3729f5dfb8061fb02.png)
- capfirst
<p>{{ st }}<p>
<p>{{ st | capfirst }}<p>
![20155953-a9d5820b3dc22c4b.png](https://i-blog.csdnimg.cn/blog_migrate/a5701d75b055e632fad42b724a53f174.png)
- cut
<p>{{ st }}<p>
<p>{{ st | cut:"hello" }}<p>
![20155953-64518d7d976ef757.png](https://i-blog.csdnimg.cn/blog_migrate/b778f1bd4fd88850ea1203d9c368140d.png)
- default
<p>{{ li }}<p>
<p>{{ li | default:"[1,2,3]" }}<p>
![20155953-1ee329e64ce953f4.png](https://i-blog.csdnimg.cn/blog_migrate/93d35f5f51d27870e3350c442eab80c3.png)
- upper
<p>{{ st }}<p>
<p>{{ st | upper }}<p>
![20155953-f634d4d43a776812.png](https://i-blog.csdnimg.cn/blog_migrate/0f0177d59191587cdfb3366c8f8415f7.png)
- lower
<p>{{ st }}<p>
<p>{{ st | lower }}<p>
![20155953-a945ebca8879fd52.png](https://i-blog.csdnimg.cn/blog_migrate/ccfb58225c04615b97e3f80744a7c25a.png)
- title
<p>{{ st }}<p>
<p>{{ st | title }}<p>
![20155953-dbb59592fa6da9c9.png](https://i-blog.csdnimg.cn/blog_migrate/2bd9194986efce68339b96fd8ffc3f3f.png)
- length
<p>{{ st }}<p>
<p>{{ st | length }}<p>
![20155953-0aa2abcb47210728.png](https://i-blog.csdnimg.cn/blog_migrate/75eb9457dbb9933762377e10e03c0eb7.png)
- slice
<p>{{ st }}<p>
<p>{{ st | slice:"2:-1" }}<p>
![20155953-feee18ff4dea9f9d.png](https://i-blog.csdnimg.cn/blog_migrate/b3e07e6f340761784532c644c5f8f70f.png)
- join
<p>{{ hobby }}<p>
<p>{{ hobby | join:"+" }}<p>
![20155953-eb438d94dca8d21a.png](https://i-blog.csdnimg.cn/blog_migrate/72e5f7d9b32ead592749648d5378a621.png)
- date
时间可以和默认值一起用,这样没有时间就可以使用默认值标注“暂缺”
<p>{{ now }}<p>
<p>{{ now|date:"Y-m-d H:i:s"}} <p>
![20155953-e414bef66275919f.png](https://i-blog.csdnimg.cn/blog_migrate/199ff93d37d3778283bc93275d97418b.png)
自定义过滤器
当普通的内置过滤器,实现不了我们的开发需求,那我们可以自定义过滤器来实现功能
自定义过滤器的流程
- 在app下创建一个名为templatetags的python包
要在settings中的INSTALLED_APPS注册当前app
注册app
- 在python中创建py文件,文件名可以自定义 如:(my_tags.py)
- 在py文件中写:
from django import template
register = template.Library() #固定写法,不可改变
- 写函数+装饰器
@register.filter #过滤器
def add_str(value, arg): # 最多有两个
return '{}-{}'.format(value, arg)
- 写页面代码
在使用自定义过滤器的html文件中导入之前创建的 my_tags.py
{% load my_tags %} #先导入我们自定义那个文件 my_tags
{{ name|add_str:age }} #参数只能是两个,一个参数是name ,一个参数是age
最终结果:
one_exa.templates.mb.html
-------------------------
<p>{{ name }}<p>
<p>{{ age }}<p>
<p>{{ name|add_str:age }} <p>
![20155953-3bced35404e739ed.png](https://i-blog.csdnimg.cn/blog_migrate/b0ffb6aa60c71ec118fcc9baa96c0ec3.png)
自定义标签
与自定义过滤器区别:
可以接受更多参数,使用标签引用{{% %}
也是在python包的templatetags文件下创建此标签
只不过可以接收更灵活的参数。
one_exa.app05.templates.my_tags.py
-----------------------------------
@register.simple_tag(name="add_max")
def plus(a, b, c):
return a+b+c
one_exa.templates.mb.html
-------------------------
<p>{{ a }}<p>
<p>{{ b }}<p>
<p>{{ c }}<p>
<p>{% add_max a b c %} <p>
![20155953-7506a6c94687d93c.png](https://i-blog.csdnimg.cn/blog_migrate/2075fe87d7d62c196840438cef7a21ea.png)
跨站请求伪造保护
在页面的form表单里面写上{% csrf_token %}
母版与继承
什么是母版
普通的HTML页面 母版页用于处理html页面相同部分内容,避免出现冗余代码,减少重复html页面的编写,提高代码复用性,方便代码修改.
继承语法
{% extends '母版文件名.html' %}
block语句块
通过在母板中使用{% block xxx %}来定义"块"。
在子页面中通过定义母板中的block名来对应替换母板中相应的内容。
#定义block
{% block 块名 %}
{% endblock %} #还可以{{% endblock 块名 %}}来关闭标签,更加清新
#使用block
{% block 块名 %}
#自己的内容
{% endblock %}
#母版内容和自己内容都使用
{% block 块名 %}
#自己的内容
{% block.super %}
{% endblock %}
注意事项:
- {% extends 'XX.html' %} 写在第一行 前面不要有内容 有内容会显示
- {% extends 'XX.html' %} 'XX.html' 加上引号 不然当做变量去查找
- 把要显示的内容写在block块中
- 定义多个block块,定义 css js 块
继承可以将我们常用的组件保存到固定的文件,例如导航条,菜单栏等等。