django模板语法

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

变量

## view.py
from django.shortcuts import render

def foo(request):
  name = "xxx" # str
  age = 18 # int
  price = 12.7 # float
  isok = True # bool
  s = {'晶晶','洋洋','嘤嘤'} # set
  return render(request,"index.html", locals())
  ## return  render(request,"index.html", {"name":views_name, ...})

## index.html
<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ price }}</p>
<p>{{ isok }}</p>
<p>{{ s }}</p>

列表,元组

## view.py
from django.shortcuts import render

def foo(request):
    li = ["xxx","123","egon"]
    t = (111,222,333,444)
    return render(request, "index.html", locals())

## index.html
"""
可以用 . 索引下标取出对应的元素
"""
<p>{{ li }}</p>   # 取出整个列表
<p>{{ t }}</p>
<p>{{ li.0 }}</p> # 取出列表的第一个元素
<p>{{ li.0.upper }}</p> # 把列表第一个元素转大写
<p>{{ t.1 }}</p>

# django模版语法的取值 是固定的格式 只能采用“句点符” .

字典

## view.py
from django.shortcuts import render

def foo(request):
    views_dict = {"name":"xxx", "age":18, 'hobby':['eat', {"book":['语文','数学']}]}
    return render(request, "index.html", {"views_dict": views_dict})

## index.html
"""
可以用 .键 取出对应的值, 不可以用get或[]去取值
"""
<p>{{ views_dict }}</p> # 取出整个字典
<p>{{ views_dict.name }}</p> # 取出name的值
<p>{{ t.hobby.1.book.1 }}</p> # 数学

函数,类

## views.py
def index(request):
    def func():
        print('我被执行了')
        return '你的另一半在等你'

    class MyClass(object):
        def get_self(self):
            return 'self'

        @staticmethod
        def get_func():
            return 'func'

        @classmethod
        def get_class(cls):
            return 'cls'

        # 对象被展示到html页面上 就类似于执行了打印操作也会触发__str__方法
        def __str__(self):
            return '到底会不会?'

    obj = MyClass()

    return render(request,'index.html',locals())

## index.html
<p>传递函数名会自动加括号调用 但是模版语法不支持给函数传额外的参数:{{ func }}</p>
<p>传类名的时候也会自动加括号调用(实例化){{ MyClass }}</p>
<p>{{ obj }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.get_func }}</p>
<p>{{ obj.get_class }}</p>

过滤器

'|' 左右不能有空格 。如果过滤器参数包含空格的话,必须用引号包裹起来。


# 基本语法
{{ 变量名 | 过滤器:可选参数 }}

"""
模板过滤器可以在变量被显示前修改它,过滤器使用管道字符

{{ name|lower }}

{{ name }} 变量被过滤器 lower 处理后,文档大写转换文本为小写。

------------------------------------------------------------------------------

过滤管道可以被套接,既是说,一个过滤器管道的输出又可以作为下一个管道的输入:

{{ my_list|first|upper }}

以上实例将第一个元素并将其转化为大写。
"""

# 带参数的过滤器
"""
{{ bio|truncatewords:"30" }}
这个将显示变量 bio 的前30个词
"""

# default
"""
default 为变量提供一个默认值。
如果 views 传的变量的布尔值是 false,则使用指定的默认值。

{{ value|default:"nothing"}}
"""

# length
"""
返回对象的长度,适用于字符串和列表
字典返回的是键值对的数量,集合返回的是去重后的长度
"""
## view.py
from django.shortcuts import render

def foo(request):
    name ="xxx"
    return render(request, "index.html", {"name": name})

## index.html
{{ name|length}}


# filesizeformat
"""
以更易读的方式显示文件的大小(即'13 KB', '4.1 MB', '102 bytes'等)

{{ value|filesizeformat}}

列如 value 是 123456789,输出将会是 117.7 MB。
"""

# date
"""
根据给定格式对一个日期变量进行格式化。
格式 Y-m-d H:i:s 返回 年-月-日 小时:分钟:秒 的格式时间
"""
## view.py
from django.shortcuts import render

def foo(request):
    import datetime
    now  =datetime.datetime.now()
    return render(request, "index.html", {"time": now})

## index.html
{{ time|date:"Y-m-d" }}


# slice
"""
对输出的字符串进行切片操作,顾头不顾尾,如果value=“egon“,则输出"eg"
支持步长
"""
{{ value|slice:'0:4:2' }}


# truncatechars
"""
如果字符串包含的字符总个数多于指定的字符数量,那么会被截断掉后面的部分。
截断的字符串将以 ... 结尾(三个点占用3个字符数量)。
eg:value="hello world egon 嘎嘎"
"""
{{ value|truncatechars:8}} # 输出"hello..."


# truncatewords
"""
同truncatechars,但truncatewords是按照单词截断(按照空格切),注意末尾的3个点不算作单词
"""
{{ value|truncatewords:2 }}

# cut
"""
移除特定的字符
"""
{{ value|cut:' ' }}

# join
"""
拼接操作
"""
{{ value|join:'$' }}


# add
"""
数字相加,字符拼接
"""
{{ value|add:10 }}


# safe
"""
Django的模板中会对HTML标签和JS等语法标签进行自动转义,这样是为了安全,防止xss攻击。如果不想用转义,就使用safe。

{{ value|safe }}
"""

# upper、lower
"""
转大写和转小写
"""

if/else 标签

# 基本语法
"""
{% if condition1 %}
   ... display 1
{% elif condition2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}

{% if %} 标签接受 and, or 或者 not 关键字来对多个变量做判断, 或者对变量取反( not )
"""

## view.py
from django.shortcuts import render

def foo(request):
    views_num = 88
    return render(request, "index.html", {"num": views_num})

## index.html
{%if num > 90 and num <= 100 %}
优秀
{% elif num > 60 and num <= 90 %}
合格
{% else %}
一边玩去~
{% endif %}

for 标签

# 基本遍历
{% for i in views_list %}
{{ i }}
{% endfor %}

# 反向遍历
{% for athlete in athlete_list reversed %}
...
{% endfor %}

# 遍历字典
{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

{% for key in dic.keys %}
    <p>{{ key }}</p>
{% endfor %}

{% for val in d.values %}
    <p>{{ val }}</p>
{% endfor %}

# {% empty %}
"""
for标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作
"""
{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

"""扩展"""
在 {% for %} 标签里可以通过 {{forloop}} 变量获取循环序号。
forloop.counter: 顺序获取循环序号,从 1 开始计算
forloop.counter0: 顺序获取循环序号,从 0 开始计算
forloop.revcounter: 倒叙获取循环序号,结尾序号为 1
forloop.revcounter0: 倒叙获取循环序号,结尾序号为 0
forloop.first(一般配合if标签使用): 第一条数据返回 True,其他数据返回 False
forloop.last(一般配合if标签使用): 最后一条数据返回 True,其他数据返回 False

## 嵌套使用 {% for %} 标签
{% for athlete in athlete_list %}
    <h1>{{ athlete.name }}</h1>
    <ul>
    {% for sport in athlete.sports_played %}
        <li>{{ sport }}</li>
    {% endfor %}
    </ul>
{% endfor %}

## for与if混合使用
{% for foo in li %}
    {% if forloop.first %}
        <p>这是我的第一次</p>
    {% elif forloop.last %}
        <p>这是最后一次啊</p>
    {% else %}
        <p>{{ foo }}</p>
    {% endif %}
    {% empty %}
        <p>for循环的可迭代对象内部没有元素 根本没法循环</p>
{% endfor %}

ifequal/ifnotequal 标签

"""
{% ifequal %} 标签比较两个值是否相等
{% ifnotequal %} 标签比较两个值是否不相等
"""
{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}

with标签

"""
with标签用来为一个复杂的变量名起别名,如果变量的值来自于数据库,在起别名后只需要使用别名即可,无需每次都向数据库发送请求来重新获取变量的值
"""
{% with li.1.upper as v %}
    {{ v }}
{% endwith %}

注释标签

## Django 注释使用 {# #}

{# 这是一个注释 #}

static标签


{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

## 引用JS文件
{% load static %}
<script src="{% static "mytest.js" %}"></script>

## 某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>

自定义过滤器、标签、inclusion_tag

"""
1.在app下创建子文件夹templatetags(文件夹名必须叫templatetags)
2.在该文件夹内创建“任意”名称的py文件 eg:mytag.py
3.在该py文件内"必须"先书写下面两句话(单词一个都不能错)
    from django import template 
    register = template.Library() # 注意变量名必须为register,不可改变
"""

# mytag.py
from django import template
register = template.Library() # 注意变量名必须为register,不可改变

#1、自定义过滤器
@register.filter(name='sum')
def my_filter(v1 ,v2): # 自定义的过滤器只能定义最多两个参数,针对{{ value1 | sum:value2 }},参数传递为v1=value1,v2=value2
    return  v1 + v2

## 使用
{% load mytag %} # 必须先加载存有自定义过滤器和标签的文件
{{ salary|sum:12 }} # salary的值为10,经过滤器my_multi_filter的处理结果为22


#2、自定义标签
@register.simple_tag(name='plus')
def my_tag(v1, v2, v3): # 自定义的标签可以定义多个参数
    return v1 * v2 * v3

## 使用
{% load mytag %}
{% plus 12 3 2 %} # 标签多个参数彼此之间空格隔开


# 3、自定义inclusion_tag
"""
内部原理
	先定义一个方法
	在页面上调用该方法 并且可以传值
	该方法会生成一些数据然后传递给一个html页面
	之后将渲染好的结果放到调用的位置
"""
@register.inclusion_tag('left_menu.html')
def left(n):
    data = ['第{}项'.format(i) for i in range(n)]
    # 第一种
    # return {'data':data}  # 将data传递给left_menu.html
    # 第二种
    return locals()  # 将data传递给left_menu.html

## 使用
{% load mytag %}
{% left 5 %}

include 标签

"""
{% include %} 标签允许在模板中包含其它的模板的内容。
"""

{% include "nav.html" %}

模板继承

"""
模板可以用继承的方式来实现复用
"""
## base.html 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>菜鸟教程 Django 测试。</p>
    {% block mainbody %}
       <p>original</p>
    {% endblock %}
</body>
</html>

"""
以上代码中,名为 mainbody 的 block 标签是可以被继承者们替换掉的部分。
所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。
"""

## index.html 中继承 base.html,并替换特定 block
{%extends "base.html" %}

{% block mainbody %}
<p>继承了 base.html 文件</p>
{% endblock %}

"""
第一行代码说明 index.html 继承了 base.html 文件。后面相同名字的 block 标签用以替换 base.html 的相应 block。

注意:!!!如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作
"""

"""
扩展:
一般情况下模版页面上应该至少有三块可以被修改的区域
1.css区域
2.html区域
3.js区域
"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% block css %}

    {% endblock %}
</head>
<body>
    {% block content %}

    {% endblock %}
</body>
    {% block js %}

    {% endblock %}
</html>

# 每一个子页面就都可以有自己独有的css代码 html代码 js代码