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 %}标签的名字必须是唯一的  

posted @ 2017-10-24 15:57  魅力宁波  阅读(184)  评论(0)    收藏  举报