Django模版

一、模板

视图函数只是返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式的HTML代码,这可以让浏览器渲染出非常漂亮的页面,目前市面上有非常多的模板系统,其中最知名最好用的是DTL和Jinja2。DTL是Django Template Language三个单词的缩写,也就是Django自带的模板语言,当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。

DTL与普通HTML文件的区别

DTL模版是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。

二、渲染模板

渲染模板有很多种方式,以下有两种常用的方式

1、render_to_string:找到模板,然后将模版编译后渲染成Python的字符串格式,然后在通过HttpResponse类包装成一个HttpResponse对象返回回去。

2、Django提供了一个更加简便的方式,直接将模板渲染成字符串和包装成HttpResponse对象,一步到位。

1、方式一:render_to_string

新建template_intro_demo项目,并在项目中加入front app,在templates中新建一个index.html

项目结构:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    body{
        background-color: pink;
    }
</style>
<body>
这个是从模板中渲染的字符串
</body>
</html>

template_intro_demo.urls.py

from django.urls import path
from front import views

urlpatterns = [
    path("", views.index, name="index"),
]

front.views.py

from django.template.loader import render_to_string
from django.http import HttpResponse

def index(request):
    html=render_to_string("index.html")
    return HttpResponse(html)

 运行结果如下:

2、方式二:render函数

更改front.views.py

from django.shortcuts import render

def index(request):
    return render(request, 'index.html')

运行结果:

二、模版查找路径配置

在预目的settings.py文件中。有一个TEMPLATES配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等。模板路径可以在两个地方配置。

DIRS:这是一个列表,在这个列表中可以存放所有的模板路径,以后在视图中使用render或者render_to_string澶染模板的时候,会在这个列表的路径中查找模板。

APP DIRS:默认为True,这个设置为True后,会在INSTALLEDAPPS的安装了的APP下的templates文件加中查找模板。

查找顺序:比如代码render('list.html")。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有,就返回。如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经安装,如果已经安装了,那么就先在当前这个app下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径下都没有找到,那么会抛出一个TemplateDoesNotExist的异常。

 在settings中有模版Templates的配置,配置的路径是

"DIRS": [BASE_DIR / 'templates']

 BASE_DIR代表项目下面的template_intro_demo

 所以模板文件需要放在项目下面的templates路径下。

新建一个test文件夹在D盘路径下

 

更改Templates配置

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [f"D:\\test"],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

此时访问http://localhost:8000/

在setting配置中还有如下配置,表示Django如果没有从DIRS目录下找到模板文件时,会从App的目录下去寻找模版文件

"APP_DIRS": True,

 将DIRS目录配置为空,并在front中新建templates文件夹,在文件夹下创建index.html

前提是app必须放在installed的app中,如果不放入installed_apps中,无法找到文件

 这样再访问http://localhost:8000/

 可以访问到front app中的templates中的模板文件。

三、模板变量使用详解

末班中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换,变量的命名规范和Python非常类似,只能是阿拉伯数字和英文字符以及下划线的组合,不能出现标点符号等特殊字符,变量需要通过视图函数渲染,视图函数在使用render或者render_to_string的时候可以传递一个context的参数,这个参数是一个字典类型,以后在模板中的变量就从这个字典中读取值的。

1、在模板中使用变量,需要将变量放到‘{{变量}}’中

2、如果想要访问对象的属性,那么可以通过‘对象.属性名’来进行访问

3、如果想要访问一个字典的key对应的value,那么只能通过‘字典.key’的方式进行访问,不能通过'中括号[]'的形式进行访问。

4、因为在访问字典的'key'时候也是使用'点.'来访问,否则字典的那个属性将变成字典中的key了。

5、如果想要访问列表或者元组,那么也是通过'点.'的方式进行访问,不能通过'中括号[]'的形式进行访问。

访问变量

新建项目template_variable_demo

 urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index),
]

 views.py

from django.shortcuts import render

def index(request):
    context={
        'username':'zhiliao'
    }
    return render(request,'index.html',context=context)

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    首页
<p>{{ username }}</p>
</body>
</html>

 运行后结果:

传递对象

views.py,传递对象Person

from django.shortcuts import render

class Person(object):
    def __init__(self, username):
        self.username = username
def index(request):
    p=Person("zhiliao")
    context={
        'person':p
    }
    return render(request,'index.html',context=context)

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ person.username }}
</body>
</html>

 运行后结果为:

传递对象属性

views.py

from django.shortcuts import render

class Person(object):
    def __init__(self, username):
        self.username = username
def index(request):
    context={
        'person':{
            'username':"zhiliao"
        }
    }
    return render(request,'index.html',context=context)

 更改index.html,访问username

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ person.username }}
</body>
</html>

 运行结果为:

获取属性关键字

views.py

from django.shortcuts import render

class Person(object):
    def __init__(self, username):
        self.username = username
def index(request):
    context={
        'person':{
            'username':"zhiliao"
        }
    }
    return render(request,'index.html',context=context)

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ person.keys }}
</body>
</html>

 运行结果如下:

如果字典中有关键字keys,则直接访问keys值

views.py

from django.shortcuts import render

class Person(object):
    def __init__(self, username):
        self.username = username
def index(request):
    context={
        'person':{
            'name':"zk",
            'keys': "帅气"
        }
    }
    return render(request,'index.html',context=context) 

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ person.keys }}
</body>
</html>

 运行结果:

获取列表中的值

 index.html

from django.shortcuts import render

class Person(object):
    def __init__(self, username):
        self.username = username
def index(request):
    context={
        'person':[
            '程咬金',
            '鲁班一号',
            '阿娇'
        ]
    }
    return render(request,'index.html',context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ person.0 }}
</body>
</html>

 运行结果:

获取元组中的值

views.py

from django.shortcuts import render

class Person(object):
    def __init__(self, username):
        self.username = username
def index(request):
    context={
        'person':(
            '程咬金',
            '鲁班一号',
            '阿娇'
        )
    }
    return render(request,'index.html',context=context)

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ person.0 }}
</body>
</html>

 运行结果:

模板中的常用标签

if标签

1、if标签相当于python中的if语句,有elif和else相对应,但是所有的标签都需要用标签符号({%%})进行包裹。if标签中可以使用==、!=、<=、>、>=、in、not in、is、is not等判断运算符。

1、所有的标签都是在‘{%%}’之间

2、if标签有闭合标签,就是{% endif %} 

3、if标签的判断运算符,就跟python中的判断运算符是一样的,'==、!=、<=、>、>=、in、not in、is、is not'这些都可以使用

4、还可以使用'elif'以及'else'标签

新建项目template_if_demo

urls.py

from django.urls import path
from template_if_demo import views

urlpatterns = [
    path("", views.index, name="index"),
]

views.py

from django.shortcuts import render

def index(request):
    context= {
        'age':17
    }
    return render(request,"index.html",context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if age < 18 %}
        <p>您是未成年人,不能进入网吧</p>
    {% elif age == 18 %}
        <p>您是成年人,能进入网吧</p>
    {% else %}
        <p>您年级太大了,不能进入网吧</p>
    {% endif %} 
</body>
</html>

 运行结果:

更改views.py

from django.shortcuts import render

def index(request):
    context= {
        'heros':[
            '鲁班一号',
            '项羽',
            '程咬金'
        ]
    }
    return render(request,"index.html",context=context)

 更改index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% if '鲁班一号' in heros %}
	<p>鲁班一号正在待命</p>
{% else %}
    <p>鲁班一号正在睡觉</p>
{% endif %} 
</body>
</html> 

 运行结果:

for...in...标签

for...in...标签:for...in...类似于Python中的for...in...,可以遍历列表、元组、字符串、字典等一切可以遍历的对象。

新建项目template_for_demo,新建urls.py和index.html

正序遍历

 urls.py

from django.urls import path
from template_for_demo import views

urlpatterns = [
    path("", views.index),
]

views.py

from django.shortcuts import render

def index(request):
    context={
        'books':[
            '三国演义',
            '红楼梦',
            '西游记',
            '水浒传'
        ]
    }
    return render(request, 'index.html',context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for book in books %}
            <li>{{ book }}</li>
        {% endfor %}
    </ul>
</body>
</html>

 运行结果:

反序遍历

更改index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for book in books reversed %}
            <li>{{ book }}</li>
        {% endfor %}
    </ul>
</body>
</html>

 运行结果如下:

遍历字典的时候,需要使用items、keys和value等方法,在DTL中,执行一个方法不能使用圆括号的形式。

更改views.py

from django.shortcuts import render

def index(request):
    context={
        'person':{
            'username':'zhiliao',
            'age':23,
            'height':100,
        }
    }
    return render(request, 'index.html',context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for key in person.keys %}
        	<li>{{ key }}</li>
        {% endfor %}
    </ul>
    <ul>
        {% for value in person.values %}
        	<li>{{ value }}</li>
        {% endfor %}
    </ul>
    <ul>
        {% for key,value in person.items %}
        	<li>{{ key }}/{{ value }}</li>
        {% endfor %}
    </ul>
</body>
</html>

 运行结果:

在for循环中,DTL提供了一些变量可供使用,这些变量如下:

1、forloop.counter:当前循环的下标,以1作为起始值

views.py

from django.shortcuts import render

def index(request):
    context={
        'books':[
            {
                'name':'三国演义',
                'author':'罗贯中',
                'price':199
            },
            {
                'name': '水浒传',
                'author': '施耐庵',
                'price': 200
            },
            {
                'name': '西游记',
                'author': '吴承恩',
                'price': 201
            },
            {
                'name': '红楼梦',
                'author': '曹雪芹',
                'price': 202
            },
        ]
    }
    return render(request, 'index.html',context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
        <thead>
        <tr>
            <td>序号</td>
            <td>书名</td>
            <td>作者</td>
            <td>价格</td>
        </tr>
        </thead>
        <tbody>
        {% for book in books %}
            <tr>
                <td>{{ forloop.counter  }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.price }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</body>
</html>

 运行结果如下:

2、forloop.counter0:当前循环的下标,以0作为起始值

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
        <thead>
        <tr>
            <td>序号</td>
            <td>书名</td>
            <td>作者</td>
            <td>价格</td>
        </tr>
        </thead>
        <tbody>
        {% for book in books %}
            <tr>
                <td>{{ forloop.counter0  }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.price }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</body>
</html> 

 输出结果:

3、forloop.recounter:当前循环的反向下标值,比如列表中有5个元素,那么第一次遍历这个属性是等于5,第二次是4,以此类推。并且是以1作为最后一个元素的下标。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
        <thead>
        <tr>
            <td>序号</td>
            <td>书名</td>
            <td>作者</td>
            <td>价格</td>
        </tr>
        </thead>
        <tbody>
        {% for book in books %}
            <tr>
                <td>{{ forloop.revcounter  }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.price }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</body>
</html>

 输出结果:

  

4、forloop.recounter0:类似于forloop recounter,不同的是最后一个元素的下标是从0开始的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
        <thead>
        <tr>
            <td>序号</td>
            <td>书名</td>
            <td>作者</td>
            <td>价格</td>
        </tr>
        </thead>
        <tbody>
        {% for book in books %}
            <tr>
                <td>{{ forloop.revcounter0  }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.price }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</body>
</html> 

输出结果:

5、forloop.first:是否是第一次遍历

6、forloop.last:是否是最后一次遍历

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
        <thead>
        <tr>
            <td>序号</td>
            <td>书名</td>
            <td>作者</td>
            <td>价格</td>
        </tr>
        </thead>
        <tbody>
        {% for book in books %}
            <tr>
                {% if forloop.first %}
                	<tr style="background-color: red;">
                {% elif forloop.last  %}
                    <tr style="background-color: pink;">
                {% else %}
                    <tr>
                {% endif %} 
                <td>{{ forloop.revcounter0  }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.price }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</body>
</html>

 输出结果:

7、forloop.parentloop:如果有多个循环嵌套,那么这个属性代表的是上一级的for循环

8、for...in...empty标签:这个标签和for...in...是一样的,只不过是在遍历的对象中如果没有元素的情况下,会执行empty中的内容。

views.py

from django.shortcuts import render

def index(request):
    context={
        'comments':[]
    }
    return render(request, 'index.html',context=context)

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for comment in comments %}
            <li>{{ comment }}</li>
        {% empty %}
            <li>没有任何评论</li>
        {% endfor %}
    </ul>
</body>
</html> 

 运行结果:

模版中的for...in...没有continue和break语句,这一点和Python中有很大的不同。

with标签

with标签:在模版中定义变量,有时候一个变量访问的时候比较复杂,那么可以先把这个复杂的变量缓存在一个变量上,以后直接使用这个变量就可以了。

1、在模版中,想要定义变量,可以使用with语句来实现

2、with语句有两种使用方式,一种是"with xxxx"的形式,第二种是"with xxx as xxx"的形式。

3、定义的变量只能在with语句中使用,在with语句块外面使用取不到这个变量。

新建一个工程template_with_demo

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index),
]

views.py  

from django.shortcuts import render

def index(request):
    context={
        'persons':[
            '张三',
            '李四',
            '王五'
        ]
    }
    return render(request, 'index.html',context=context) 

with用法一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{%  with zhangsan=persons.0 %}
<p>{{ zhangsan  }}</p>
<p>{{ zhangsan  }}</p>
{% endwith %}
</body>
</html>

运行结果:

with用法二:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% with persons.0 as zs %}
	<p>{{ zs }}</p>
{% endwith %}
</body>
</html>

运行结果:

Url标签

url标签:在模版中,我们经常要写一些url,比如某个‘a’标签中需要定义'href'属性,当然如果通过编码的方式直接将这个'url'写死在里面也是可以。但是这样对于以后项目的维护可能不是一件好事,因此建议使用这种反转的方式来实现,类似于django中的reverse一样。示例代码如下:

新建项目template_url_demo

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index,name="index"),
    path("book/", views.books,name="books"),
    path("book/detail/<book_id>/<category>", views.books_detail,name="books_detail"),
    path("movie/", views.movies,name="movies"),
    path("city/", views.city,name="city"),
    path("login/",views.login,name="login"),
]

views.py

from django.http import HttpResponse
from django.shortcuts import render

def index(request):
    return render(request, 'index.html')

def login(request):
    next = request.GET.get('next')
    text="登录页面,登陆完成后要跳转的url是 %s"%next
    return HttpResponse(text)

def books(request):
    return HttpResponse("读书页面")

def books_detail(request,book_id,category):
    res="您的书籍id是%s 书籍分类是%s" %(book_id,category)
    return HttpResponse(res)

def movies(request):
    return HttpResponse("电影页面")

def city(request):
    return HttpResponse("城市页面")

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .nav{
            overflow: hidden;
        }
        .nav li{
            float: left;
            list-style: none;
            margin: 0 0 20px 20px ;
        }
    </style>
</head>
<body>
    <ul class="nav">
        <li><a href="/">首页</a></li>
        <li><a href="{% url 'books' %}">读书</a></li>
        <li><a href="{% url 'movies' %}">电影</a></li>
        <li><a href="{% url 'city' %}">同城</a></li>
        <li><a href="{% url 'books_detail' book_id='1' category=1 %}">最火的一篇文章</a></li>
        <li><a href="{% url 'login' %}?next=/">登录</a></li>
    </ul>
</body>
</html>

运行结果:

Spaceless标签

Spaceless标签:移除html标签中的空白字符,包括空格、tab键、换行等。示例代码如下:

{% spaceless %}
	    <p>
            <a href="{% url 'books' %}">读书</a>      
        </p>
{% endspaceless %} 

可以看到移除空白字符之后的代码如下:

autoescape标签

1、DTL中默认开启了自动转义,会将哪些特殊字符进行转义,比如会将'<'转移成'&lt;'等。

2、使用DTL的自动转义,可以使网站不容易出现XSS漏洞。

3、如果变量确实是可信任的,那么可以使用'autoescape'标签来关掉自动转义。

新建一个项目工程template_autoescape_demo项目

 urls.py

from django.urls import path
from template_autoescape_demo import views

urlpatterns = [
    path("", views.index, name="index"),
]

views.py

from django.shortcuts import render

def index(request):
    context={
        'info':"<a href='www.baidu.com'>百度</a>"
    }
    return render(request, 'index.html',context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{  info  }}
<a href='https://www.baidu.com'>百度</a>
</body>
</html> 

 运行结果如下:

 查看网页源代码可以看到网页中的html源码是经过转义的

现在关闭自动转义源代码,更改index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% autoescape off %}
{{  info  }}
{% endautoescape %}
<a href='https://www.baidu.com'>百度</a>
</body>
</html>

 运行结果如下:

关闭自动转义以后,模版文件html会自动渲染

verbatim标签

默认在DTL模板中是会去解析那些特殊字符的。比如{%和%}以及{{等。如果你在某个代码片段中不想使用DTL的解析引擎。那么你可以把这个代码片段放在verbatim标签中。示例代码如下:

新建项目template_verbatim_demo

 urls.py

from django.urls import path

from template_verbatim_demo import views

urlpatterns = [
    path("", views.index),
]

views.py

from django.shortcuts import render

def index(request):
    context={
        'hello':"hello"
    }
    return render(request, 'index.html',context=context)

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% verbatim %}
        {{ hello }}
    {% endverbatim %}
</body>
</html> 

运行结果如下:

可以看到模版文件中没有解析context参数中的hello字段

其他模版标签可以查看网址https://docs.djangoproject.com/en/2.0/ref/templates/builtins/

模板常用的过滤器

在模版中,有时候需要对一些数据进行处理以后才能使用,一般在Python中我们是通过函数的形式来完成的。而在模板中,则是通过过滤器来实现的。过滤器使用的是"|"来使用。

因为在DTL中,不支持函数的调用形式"()",因此不能给函数传递参数,这将有很大的局限性,而过滤器其实就是一个函数,可以对需要处理的参数进行处理,并且还可以额外接收一个参数(也就是说,最多只能有两个参数)

新建一个项目template_filter_demo

add过滤器

将传进来的参数添加到原来的值上面,这个过滤器会尝试将"值"和"参数"转换成整型然后进行相加,如果转换成整型过程中失败了,那么会将"值"和"参数"进行拼接。如果是字符串,那么会拼接成字符串,如果是列表,那么会拼接成一个列表。

数字拼接

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("",views.index,name="index"),
    path("add/",views.add_view,name="index"),
]

views.py

from django.shortcuts import render

def greet(word):
    return 'Hello World! %s' % word

def index(request):
    context={
        'greet':2
    }
    return render(request,'index.html',context=context)

def add_view(request):
    return render(request,'add.html')

add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>add过滤器</title>
</head>
<body>
{{ "1" | add:"2" }}
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ greet | add:"2" }}
</body>
</html> 

访问index.html

访问add.html

字符串拼接

更改index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ greet | add:"2ssss" }}
</body>
</html> 

 更改views.py

from django.shortcuts import render

def greet(word):
    return 'Hello World! %s' % word

def index(request):
    context={
        'greet':'2'
    }
    return render(request,'index.html',context=context)

def add_view(request):
    return render(request,'add.html') 

 输出结果如下:

列表拼接

views.py

from django.shortcuts import render

def greet(word):
    return 'Hello World! %s' % word

def index(request):
    context={
        'greet':'2'
    }
    return render(request,'index.html',context=context)

def add_view(request):
    context={
        'value1':['1','2','3'],
        'value2':['4','5','6'],
    }
    return render(request,'add.html',context=context)

 add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>add过滤器</title>
</head>
<body>
{{ value1 | add:value2 }}
</body>
</html>

 输出结果:

cut过滤器

移除值中所有指定的字符串。

views.py

from django.shortcuts import render

def cut_view(request):
    return render(request,'cut.html')

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("cut/",views.cut_view,name="cut"),
]

cut.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ "h e l l o"|cut:" " }}
</body>
</html>

 运行结果如下:

date过滤器

讲一个日期按照指定的格式,格式化成字符串,示例代码如下:

date格式化输出方式

格式字符 描述 示例
Y 四位数字的年份 2018
m 两位数字的月份 01-12
n 月份,1-9没有前面的0格式 1-12
d 两位数字的天 01-31
j 天,但是1-9前面没有0前缀 1-31
g 小时,12小时格式的,1-9前面没有0的前缀 1-12
h 小时,12小时格式的,1-9前面有0的前缀 01-12
G 小时,24小时格式的,1-9前面没有0的前缀 1-23
H 小时,24小时格式的,1-9前面有0的前缀 01-23
i 分钟,1-9前面有0的前缀 01-59
s 秒,1-9前面有0的前缀 00-59

 修改views.py

from datetime import datetime
from django.shortcuts import render

def date_view(request):
    context={
        'today':datetime.now()
    }
    return render(request,'date.html',context=context) 

修改urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("date/",views.date_view,name="date"),
]

新建date.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>date</title>
</head>
<body>
{{ today|date:"Y/m/d H:i:s" }}
</body>
</html>

 运行结果如下:

default过滤器

如果值被评估为False,比如[],"",None,{}等这些在if判断中为False的值,都会使用default过滤器提供的默认值。

示例代码如下:

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("default/",views.default_view,name="default"),
]

views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value':'',
    }
    return render(request,"default.html",context=context)

default.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>default</title>
</head>
<body>
{{ value|default:"我是默认值"}}
</body>
</html>

 当value值为空值时,会用default缺省值替代 

运行结果如下:

更改views.py

from datetime import datetime
from django.shortcuts import render


def default_view(request):
    context={
        'value':'不使用缺省值',
    }
    return render(request,"default.html",context=context)

 运行结果如下:

如果为空列表

views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value':[],
    }
    return render(request,"default.html",context=context) 

 也会使用缺省值

如果使用空字典

views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value': {},
    }
    return render(request,"default.html",context=context) 

 运行结果如下:

如果是None值

views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value': None,
    }
    return render(request,"default.html",context=context)

 运行结果如下:

default_if_none过滤器

如果值是None,那么将会使用default_if_none提供的默认值,这个和default有区别,default是所有被评估为False的都会使用默认值,而default_if_none则只有这个值是等于None的时候才会使用默认值。

views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value': None,
    }
    return render(request,"default.html",context=context)

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("default/",views.default_view,name="default"),
]

 default.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>default</title>
</head>
<body>
{{ value|default_if_none:"我是默认值"}}
</body>
</html> 

 运行结果如下:

更改views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value': '',
    }
    return render(request,"default.html",context=context)

 运行结果如下:

因为值为空不为None,不使用缺省值

更改views.py

from datetime import datetime
from django.shortcuts import render

def default_view(request):
    context={
        'value': {},
    }
    return render(request,"default.html",context=context)

 运行结果如下:

first过滤器

返回列表/元组/字符串中的第一个元素。

views.py

from datetime import datetime
from django.shortcuts import render

def first_view(request):
    context={
        'value': [1,2,3,4,5,6,7,8,9],
    }
    return render(request,"first.html",context=context)

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("first/",views.first_view,name="first"),
]  

first.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>first</title>
</head>
<body>
{{ value|first }}
</body>
</html> 

运行结果如下:

last过滤器

返回列表/元组/字符串中的最后一个元素。

views.py

from datetime import datetime
from django.shortcuts import render

def last_view(request):
    context={
        'value': [1,2,3,4,5,6,7,8,9],
    }
    return render(request,"last.html",context=context) 

 urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("last/",views.last_view,name="last"),
]

last.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>last</title>
</head>
<body>
{{ value|last }}
</body>
</html>

 运行结果如下:

floatformat过滤器

使用四舍五入的方式格式化一个浮点类型,如果这个过滤器没有传递任何参数。那么只会在小数点后保留一个小时,如果小数点后面全是0,那么只会保留整数。当然也可以传递一个参数,标识具体要保留几个小数

1、如果没有传递参数

value 模板代码 输出
32.23234 {{ value|floatformat }} 32.2
34.000 {{ value|floatformat }} 34
34.260 {{ value|floatformat }} 34.3

示例代码如下:

views.py

from datetime import datetime
from django.shortcuts import render

def floatformat_view(request):
    context={
        'value': 32.23234
    }
    return render(request,"floatformat.html",context=context)

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("floatformat/",views.floatformat_view,name="floatformat"),
]

floatformat.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>floatformat</title>
</head>
<body>
{{ value|floatformat }}
</body>
</html>

 输出结果如下:

更改值

views.py

from datetime import datetime
from django.shortcuts import render

def floatformat_view(request):
    context={
        'value': 34.000
    }
    return render(request,"floatformat.html",context=context)

更改值

views.py

from datetime import datetime
from django.shortcuts import render

def floatformat_view(request):
    context={
        'value': 34.260
    }
    return render(request,"floatformat.html",context=context) 

2、如果传递参数:

value 模板代码 输出
34.23234 {{ value|floatformat:3 }} 34.232
34.00000 {{ value|floatformat:3}} 34.000
34.26000 {{ value|floatformat:3 }} 34.260

示例代码如下:

更改floatformat.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>floatformat</title>
</head>
<body>
{{ value|floatformat:3 }}
</body>
</html> 

views.py

from datetime import datetime
from django.shortcuts import render

def floatformat_view(request):
    context={
        'value': 34.260
    }
    return render(request,"floatformat.html",context=context)

运行结果如下:

Join过滤器

类似于Python中的join,将列表/字符串用指定的字符进行拼接。 

views.py

from datetime import datetime
from django.shortcuts import render

def join_view(request):
    context={
        'value':[1,2,3]
    }
    return render(request,"join.html",context=context)

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("join/",views.join_view,name="join"),
]

join.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ value|join:"/" }}
</body>
</html>

 运行结果如下:

length过滤器

获取一个列表/元组/字符串的长度

 views.py

from datetime import datetime
from django.shortcuts import render

def length_view(request):
    context={
        'value':[1,2,3,5,6,7,8]
    }
    return render(request,"length.html",context=context)

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("length/",views.length_view,name="length"),
]

length.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>length</title>
</head>
<body>
{{ value|length }}
</body>
</html>

 运行结果如下:

lower过滤器

将值中所有的字符转换为小写,示例代码如下:

views.py

from datetime import datetime
from django.shortcuts import render

def lower_view(request):
    context={
        'value':"SDFADADA"
    }
    return render(request,"lower.html",context=context)

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("lower/",views.lower_view,name="lower"),
]

lower.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>lower</title>
</head>
<body>
{{ value|lower }}
</body>
</html> 

运行结果如下:

upper过滤器

将值中所有的字符转换为大写,示例代码如下:

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("upper/",views.upper_view,name="upper"),
]

views.py

from datetime import datetime
from django.shortcuts import render

def upper_view(request):
    context={
        'value':"sasasasad"
    }
    return render(request,"upper.html",context=context)

upper.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>upper</title>
</head>
<body>
{{ value|upper }}
</body>
</html>

 运行结果如下:

random过滤器

随机的在列表/字符串/元组中选择一个值

 urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("random/",views.random_view,name="random"),
]

views.py

from datetime import datetime
from django.shortcuts import render

def random_view(request):
    context={
        'value':(1,2,3,4,5,6)
    }
    return render(request,"random.html",context=context)

 random.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>random</title>
</head>
<body>
{{ value|random }}
</body>
</html>

 运行结果如下:

safe过滤器

标记一个字符串是安全的,也就是关闭这个字符串的自动转义

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("safe/",views.safe_view,name="safe"),
]

views.py

from datetime import datetime
from django.shortcuts import render

def safe_view(request):
    context={
        'value':"<script>alert('hello');</script>"
    }
    return render(request,"safe.html",context=context)

safe.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>safe</title>
</head>
<body>
{{ value|safe }}
</body>
</html>

输出结果如下:

 

查看源代码

相当于字符串转变为js代码

slice过滤器

类似于Python中的切片操作。示例代码如下:

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("slice/",views.slice_view,name="slice"),
]

views.py

from django.shortcuts import render

def slice_view(request):
    context={
        'value':[1,2,3,4,5,6,7,8,9,10]
    }
    return render(request,"slice.html",context=context)

 

slice.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>slice</title>
</head>
<body>
{{ value|slice:"2:" }}
</body>
</html>

运行结果如下:

 

取2后面的值

设置步长

 slice.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>slice</title>
</head>
<body>
{{ value|slice:"1::2" }}
</body>
</html>

 运行结果如下:

stringtags标签

删除字符串中所有的html标签。示例代码如下

urls.py

from django.urls import path
from template_filter_demo import views

urlpatterns = [
    path("stringtags/",views.stringtags_view,name="string_tags"),
]

views.py

from datetime import datetime
from django.shortcuts import render

def stringtags_view(request):
    context={
        'value':'<script>alert("hello");</script>'
    }
    return render(request,"stringtags.html",context=context)

stringtags.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Stringtags</title>
</head>
<body>
{{ value|striptags }}
</body>
</html> 

 运行结果如下:

删除了<scripts>标签

truncatechars标签

如果指定的字符串长度超过了过滤器指定的长度,那么就会进行切割,并且会拼接三个点来作为省略号。示例代码如下:

 

 

 

  

 

 

  

 

  

 

 

  

 

  

  

  

 

  

  

 

  

  

  

  

  

  

 

posted @ 2024-06-10 22:21  leagueandlegends  阅读(21)  评论(0编辑  收藏  举报