Django模板语言
一、模板语法之变量
模板语法的变量的用法如下:
{{ 变量名 }} #在HTML文件的任意位置按此格式定义一个模板的变量
#在view中的函数以如下方式将值传递给模板去渲染模板中的对应变量
def index(request):
import datetime
s="hello"
l=[111,222,333] # 列表
dic={"name":"yuan","age":18} # 字典
date = datetime.date(1993, 5, 2) # 日期对象
class Person(object):
def __init__(self,name):
self.name=name
person_yuan=Person("yuan") # 自定义类对象
person_egon=Person("egon")
person_alex=Person("alex")
person_list=[person_yuan,person_egon,person_alex]
return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list}) #在render方法的第三个参数中以字典的形式向模板传入需要渲染的值,格式为{'模板变量名':视图函数的变量},也可以用locals()方法将所有变量按名字一一对应的传递
模板变量可以用英文的句号进行深度变量,即以如下格式取值:
<h4>{{s}}</h4> <h4>列表:{{ l.0 }}</h4> <h4>列表:{{ l.2 }}</h4> <h4>字典:{{ dic.name }}</h4> <h4>日期:{{ date.year }}</h4> <h4>类对象列表:{{ person_list.0.name }}</h4> <h4>无参的类方法:{{person_list.0.dream}}</h4> <h4>字典:{{ dic.name.upper }}</h4>
二、模板语法之过滤器
过滤器的语法和变量类似,格式如下
<p>{{变量名|过滤器名:参数}}</p> #一个过滤器只能接收两个参数,可以作为if的条件
常用的内置过滤器如下:
default:当变量的值为false或为空使用默认值,否则使用变量值
{{ value|default:"nothing" }}
length:返回变量的值的长度,对字符串和列表有效
{{ value|length }}
filesizeformat:将文件的大小以KB、MB等易读的单位显示
{{ value|filesizeformat }}
date:当变量值为datetime.datetime.now(),截取需要的部分
{{ value|date:"Y-m-d" }}
slice:切片
{{ value|slice:"2:-1" }}
truncatechars:截断字符串,以省略号作为结尾
{{ value|truncatechars:9 }}
safe:当变量值为HTML标签时,表示该变量值是安全的可以按HTML格式显示
{{ value|safe}}
三、模板语法之标签
模板标签的语法比变量稍微复杂一点,按如下格式书写:
{% 标签名 %}
标签内容
{% end标签名 %}
常用的内置标签如下:
for: <!--遍历列表--> {% for person in person_list %} <p>{{ person.name }}</p> {% endfor %} <!--反向遍历列表--> {% for obj in list reversed %} <p>{{ person.name }}</p> {% endfor %} <!--遍历字典--> {% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %} <!--循环序号--> {% for person in person_list %} <p>{{forloop.counter}}{{ person.name }}</p> {% endfor %} <!--循环序号还有如下语法--> forloop.counter The current iteration of the loop (1-indexed) forloop.counter0 The current iteration of the loop (0-indexed) forloop.revcounter The number of iterations from the end of the loop (1-indexed) forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) forloop.first True if this is the first time through the loop forloop.last True if this is the last time through the loop
for......empty: {% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <!--当变量值为空或者没有找到时显示该子句下的内容--> <p>sorry,no person here</p> {% endfor %} if: {% if num > 100 or num < 0 %} <p>无效</p> {% elif num > 80 and num < 100 %} <p>优秀</p> {% else %} <p>凑活吧</p> {% endif %} with:用变量存储一个不容易获得的值(如访问数据库) {% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %} csrf_token:生成一个不可见的input标签,name='csrfmiddlewaretoken' value='一个随机字符串',用于防止非正常访问服务器的链接向服务器提交数据 <form action='xxxx' method='post'> {% csrf_token %} <input type='text' /> <input type='submit'> </form>
四、自定义过滤器和标签
由于内置的过滤器和标签无法完全满足我们日常开发的需求,所以需要我们按照自己的需求自定义过滤器和标签,具体步骤如下:
1、在settings中的INSTALLED_APPS写入应用的名字,不然django无法找到自定义的simple_tag.
in settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01']
2、在app中创建templatetags包(模块名只能是templatetags)
3、创建任意 .py 文件,如:my_tags.py
from django import template from django.utils.safestring import mark_safe register = template.Library() #register的名字是固定的,不可改变 #上面三句是固定的 @register.filter #定义过滤器使用该装饰器 def filter_multi(v1,v2): #过滤器的逻辑 return v1 * v2 @register.simple_tag #定义标签使用该装饰器 def simple_tag_multi(v1,v2): #标签的逻辑 return v1 * v2
@register.inclusion_tag('menus.html') #inclusion_tag可以拿到被装饰函数的返回值去渲染括号中的模板,然后将html代码放到引用该标签的位置
def menu_html(request):
current_url=request.path_info
menu_list=request.session.get(settings.ACCESS_MENU_KEY)
menu_dicts={}
for menu_dict in menu_list:
url=menu_dict['access_url']
url='^{0}$'.format(url)
active=False
if re.match(url,current_url):
active=True
menu_id=menu_dict['menu_id']
if menu_id in menu_dicts:
menu_dicts[menu_id].children.append({'title':menu_dict['access_title'],'url':menu_dict['access_url'],'active':active},)
if active:
menu_dicts[menu_id].active=active
else:
menu_dicts[menu_id]={
'menu_id':menu_id,
'menu_title':menu_dict['menu_title'],
'active':active,
'children':[{'title':menu_dict['access_title'],'url':menu_dict['access_url'],'active':active},]
}
return {'menu_dicts':menu_dicts}
4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{% load my_tags %} <!--在使用自定义过滤器和标签之前的位置导入即可--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> </body> </html>
5、使用
{% load xxx %}
# num=12
{{ num|filter_multi:2 }} #24
{{ num|filter_multi:"[22,333,4444]" }}
{% simple_tag_multi 2 5 %} 标签的参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}
{% if num|filter_multi:30 > 100 %} 过滤器只能接收两个参数,可以作为if的条件
{{ num|filter_multi:30 }}
{% endif %}
五、模板继承
父模板base.html:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>{% block title %}My amazing site{% endblock %}</title> </head> <body> <div id="sidebar"> {% block sidebar %} <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> {% endblock %} </div> <div id="content"> {% block content %}{% endblock %} </div> </body> </html>
子模版:
{% extends "base.html" %} <!--声明继承哪个父模板-->
{% block title %}My amazing blog{% endblock %} <!--按顺序替换父模板中的block标签-->
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
使用模板继承的需要注意的地方:
1、{% extends %}标签必须是子模版的第一个标签
2、父模板中尽可能多的定义{% block %}标签,并且可以在每个{% block %}标签中定义合理的默认内容,而子模版只需要重新定义其中的某一些{% block %}标签的内容,其余使用父模板的默认内容即可
3、如果某个{% block %}标签的内容既想写入新的内容又想使用父模板的内容,可以写上{{ block.super }}标签即可继承父模板对应位置的所有内容
4、为了更好的可读性,可以在block标签的结束位置写上名字,比如{% block content %}...{% endblock content %}
5、同一个模板中每个{% block %}标签的名字必须是唯一的

浙公网安备 33010602011771号