Django(模板语言)
一.语法
关于模板渲染你只需要记两种特殊符号:{{ }}和 {% %}
变量相关的用{{}},逻辑相关的用{%%}
二.过滤器
1.过滤器认识
1.过滤器的语法: {{ value|filter_name:参数 }} 2.使用管道符"|"来应用过滤器。 注意点: 1.过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。 2.过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。 3.过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }} 4.'|'左右没有空格
2.过滤器方法使用
default
{{ value|default:"nothing"}} #如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
length
{{ value|length }} #返回值的长度,作用于字符串和列表
filesizeformat
{{ value|filesizeformat }} #将值格式化为文件尺寸(例如 '13 KB', '4.1 MB', '102 bytes', 等等)
slice
#切片 {{value|slice:"2:-1"}}
date
#格式化,如果 value=datetime.datetime.now() {{ value|date:"Y-m-d H:i:s"}}
safe
#让链接value = "<a href='#'>点我</a>" 渲染,加上safe {{ value|safe}}
{% autoescape off %} #同上safe作用 {{ obj }} {% endautoescape %}
truncatechars
#字符截断,多余的使用...来表示 {{ value|truncatechars:9}} #注意:最后那三个省略号也是9个字符里面的
truncatewords
#截多少个单词(通过空格截断) {{ value|truncatewords:3}} #例如:‘hello girl hi baby yue ma’,结果是 'hello girl h1...'
cut
{{ value|cut:' ' }} #移除value中的所有空格
join
使用字符串连接列表,{{ list|join:', ' }},就像Python的str.join(list)
add
#value后边添加2 {{ value|add:"2" }}
urlencode
{{ obj|urlencode }} 将obj编码 http://www.baidu.com/ ->http%3A//www.baidu.com
三.标签tags
语法
{% tag %}
...内容
{% endtag %}
1.for标签
遍历一个字典: {% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %}
forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
#for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。 {% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>sorry,no person here</p> {% endfor %}
2.if标签
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。
{% if num > 100 or num < 0 %} <p>无效</p> <!--不满足条件,不会生成这个标签--> {% elif num > 80 and num < 100 %} <p>优秀</p> {% else %} <!--也是在if标签结构里面的--> <p>凑活吧</p> {% endif %}
3.with标签
用于给复杂变量赋值
{% with total=business.employees.count %} {{ total }} <!--只能在with语句体内用--> {% endwith %}
4.csrf_token
在form表单点击提交按钮后,会出现Forbidden:CSRF verification failed. Request aborted,解决方法两种
方法一:在settings.py中注释掉 'django.middleware.csrf.CsrfViewMiddleware',
方法二:在form表单中 添加这个模板语言
<form action="/index/" method="post"> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="submit" value="submit"> {% csrf_token %} </form>
5.verbatim
#禁止render,也就是说传给浏览器的内容是 {{hello}} {% verbatim %} {{ hello }} {% endverbatim %}
6.static
静态文件引入
html文件上方 --{% load static%} <link href='{% static "css/b.css" %}'>
四.组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中(如:navbar.html),然后在需要使用的地方按如下语法导入即可。
{% include 'navbar.html' %}
五.自定义filter和simple_tag
filter过滤器的主要形式:变量|函数,意思是将变量交给函数处理,而自定义filter就是自己定义函数,因为用到已有的很少。
1.自定义filter和simple_tag
1.在当前app中创建templatetags模块(templatetags名称固定)
2.在templatetags中创建.py文件,如my_tags.py
from django import template from django.utils.safestring import mark_safe register = template.Library() #register的名字是固定的,不可改变 #1.register.filter @register.filter def filter_multi(v1,v2): return v1 * v2 #2.register.simple_tag @register.simple_tag def simple_tag_multi(v1,v2): return v1 * v2 @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result) #mark_safe保证生成标签
3.在html中导入之前创建的my_tags.py:{% load my_tags%}
4.使用filter和simple_tags
{% load xxx %} #首行 1.使用filter,最多能传2个参数 {{ num|filter_multi:2 }} #24 <!---最多2参数,能放在if for语句中---> {{ num|filter_multi:"[22,333,4444]" }} 2.使用simple_tag,能传多个参数 {% simple_tag_multi 2 5 %} <!---参数不限,但不能放在if for语句中---> {% simple_tag_multi num 5 %}
自定义filter和simple_tag区别:
1.filter最多传2参数,simple_tags能传多个参数
2.filter的调用可写在for/if语句中,simple_tags不可
{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}
2.inclusion_tag
from django import template from django.utils.safestring import mark_safe register = template.Library() #Library首字母大写 @register.inclusion_tag('index.html') def res(n1): return {"li":n1} #base.html中{% res li%}调用了res方法,将其li值作为参数传递给参数n1,因为有@register.inclusion_tag('index.html')的作用,将res的返回值{"li":n1}以render渲染方式给了index.html中的li变量,然后将index.html作为控件再被base.html引入。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% for i in li %} <p>{{ i }}</p> {% endfor %} </body> </html>
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^base/',views.base), ]
from django.shortcuts import render,HttpResponse,rediret def base(req): li = [11,22,33] return render(req,"base.html",{"li":li})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>母板</title> </head> <body> {% load my_tags %} <!---导入my_tags.py---> {% res li %} <!---调用my_tags.py中的res方法,将li传值给它---> </body> </html>
六.模板继承extends
我们在写前端界面时,通常会遇到多个界面有相同的部分,那么如何避免这种问题的发生?就要用到模板继承。继承思路:(将不同界面中的共同部分取出来,单独写入一个html,作为母板,然后其他界面继承于此界面)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>母板</title> </head> <body> <div> <!---div中的菜单为son1.html,son2.html的共同部分---> <p>菜单一</p> <p>菜单二</p> <p>菜单三</p> </div> {% block content %} 这里写不同的部分 {% endblock %} </body> </html>
{% extends 'base.html' %} <!---继承于base.html---> {% block content%} 这是son1 {% endblock %}
{% extends 'base.html' %}
{% block content%}
这是son2
{% endblock %}
七.全局模板
在html中要使用django中的python部分的变量,首先在对应的app中(此处为produce)新建context_processors.py文件
from django.conf import settings def childids(request): #此处需返回字典(html中直接使用键{{CHILD_JOURNAL_IDS}}) return {"CHILD_JOURNAL_IDS":settings.CHILD_JOURNAL_IDS}
setting.py中引用
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR + '/templates', JOURNAL_TEMPLATES_MOUNT_DIRECTORY], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'produce.context_processors.childids', ], }, }, ]