在上篇文章中,我们提到过,通过模板语言的循环标签.values能获取到对应字典的键值,且不需要在values属性加括号,这是为什么呢? 这是因为django中的模板语言,还有一个用于进行模板过滤的函数
,本质是调用python带装饰器的函数
,与模板语言搭配使用,所以我们即可调用,也可自行定制。而调用的时候也得遵循它得规则,即 { {值 | 函数:“参数”}}
,方可使用,这种模板里定义函数,我们就称之为simple_filter
。且注意在使用|的时候不能有空格
,不然会报错。
常见的过滤器如下:
过滤器 | 含义 | 举例 |
---|---|---|
length | 获取一个列表、元组、字符串、字典的长度 | { { value|length }} |
lower | 将变量中所有的字符全部转换成小写 | { { value|lower }} |
upper | 将指定的字符串全部转换成大写 | { { value|upper }} |
random | 在给定的列表、字符串、元组中随机选择一个值 | { { value|random }} |
safe | 标记字符串是安全的,如果值是一串html代码,会将html代码渲染到浏览器中。 | { { value|safe}} |
add | 通过 { {值 | add:"字段"}}返回计算结果(可以是字符串) | { { value|add}} |
cut | 用于移除值中所有指定的字符串,类似于Python的replace()方法。 | { { value|cut}} |
slice | 类似于Python中的切片操作,对列表、字符串等进行切片。 | { { value|slice}} |
default | 判断是否为空(空的话可以用该方法将其替换) | { { value|default}} |
过滤器的使用方法有很多,不同场合不同用法,在有意义的情况下,可以搭配任意模板语言即循环标签一起使用。下面我们就来展示一下,常用过滤器的一些用法吧!
urls如下:
from django.urls import path
from app01 import views
urlpatterns = [
path('test/', views.test, name="test"),
]
app01/views如下:
from django.shortcuts import render, HttpResponse
def test(request):
context = {
'num': "3", 'char': 'aaa',
'html_url': '我是一个h1标签
',
'letter': 'Happy year of the ox',
'data_list': ['小红', '小蓝', '小绿'],
'name_1': "",
'name_2':"sehun",
}
return render(request, 'test.html', context)
test.html如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<p>原数={
{ num }},原数+2={
{ num | add:"2" }}p>
<p>字符={
{ char }},字符+bbb={
{ char | add:'bbb'}}p>
<p>字符大写={
{ char | upper }},字符大写+bbb大写={
{ char | add:'bbb' | upper}}p>
<p>字符小写={
{ char | lower }},字符小写+bbb小写={
{ char | add:'bbb' | lower}}p>
<p>字符大写+bbb小写={
{ char | upper | add:"bbb" }}p>
<p>字符+bbb截取b={
{ char | add:'bbb' | cut:'b' }}p>
<hr size="1">
<p>随机值={
{ letter | random }}p>
<hr size="1">
<p>{
{ data_list | slice:'1' }},{
{ data_list | slice:'1' | length }}人p>
<p>{
{ data_list | slice:'2' }},{
{ data_list | slice:'2' | length }}人p>
<p>{
{ data_list | slice:'3' }},{
{ data_list | slice:'3' | length }}人p>
<hr size="1">
<p>{
{ html_url }}p>
<p>{
{ html_url | safe }}p>
<hr size="1">
<p>姓名:{
{ name_1 | default:"无" }}p>
<p>姓名:{
{ name_2 | default:"无" }}p>
body>
html>
此时访问127.0.0.1:8000/test/如下:
我们可以发现,过滤器的功能很多,且可以搭配一起使用
,非常的灵活。
在上面的描述中提到,过滤器是可以自定义方法的,因为其内部是调用python带装饰器的函数
,所以在使用自定义的时候也要遵循它相应的规则:
调用函数方法register=template.Library()
完成上述步骤后,我们就可以来定义一个自己的模板语言函数了。
xx.py如下:
from django.template import Library
register = Library()
@register.filter
def my_upper(value, k1):
return value + k1
urls.py如下:
from django.urls import path
from app01 import views
urlpatterns = [
path('test/', views.test, name="test"),
path('custom/', views.custom, name="custom"),
]
views.py如下:
from django.shortcuts import render, HttpResponse
def custom(request):
context = {
'data': 'sehun'}
return render(request, 'custom.html', context)
custom.html如下:
{% load xx %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
{
{ data | my_upper:"666" }}
body>
html>
此时访问127.0.0.1:8000/custom/如下:
显然结果显示出来了,而且自定义的方法也是可以传参的,不过只能有一个传参方式
,如想多传,只能用自己处理。且自定义方法也可以结合循环标签类使用。
views.py如下:
from django.shortcuts import render, HttpResponse
def custom(request):
context = {
'data': 'sehun', 'name': request.GET.get('name')}
return render(request, 'custom.html', context)
custom.html如下:
{% load xx %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
{% if data|my_bool:name %}
<p>正确p>
{% else %}
<p style="color: red">错误p>
{% endif %}
body>
html>
xx.py如下:
from django.template import Library
register = Library()
@register.filter
def my_upper(value, k1):
return value + k1
@register.filter
def my_bool(value, k1):
if k1 != value:
return False
return True
此时访问127.0.0.1:8000/custom/如下:
此时是可以配合着后台完成判断的。
自定义方法simple_tag调用方法和simple_filter类似,该方法的调用类似于{% ‘函数’ %}
和我们前面讲的循环标签,以及url,include是一个类型,该方法于simple_filter的不同点在于,可以传递多个参数
,但是不能应用于循环标签中(不过实际用法中多会用此方法,因为可以在内部完成,在返回给前端模板)。
views.py如下:
from django.shortcuts import render, HttpResponse
def custom(request):
context = {
'data': 'sehun', 'name': request.GET.get('name')}
return render(request, 'custom.html', context)
custom.html如下:
{% load xx %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
{% if data|my_bool:name %}
<p>正确p>
{% else %}
<p style="color: red">错误p>
{% endif %}
<p>{% my_lower name|default:"" "祝大家" "牛年" "快乐" %}p>
body>
html>
xx.py如下:
from django.template import Library
register = Library()
@register.filter
def my_upper(value, k1):
return value + k1
@register.filter
def my_bool(value, k1):
if k1 != value:
return False
return True
@register.simple_tag
def my_lower(value, a1, a2, a3):
return value + a1 + a2 + a3
可以看到,simple_tag是可以传多个参数,且可以配合着模板语言即过滤器使用
进行搭配使用,当然自定义方法也都是可以的。
自定义方法inclusion_tag方法和simple_tag类似,听名字大家也应该能猜到,inclusion_tag方法类似上节我们讲到的include函数+simple_tag合体版,可以在定义装饰器的时候指定html路径,然后在模板中{% “函数” %}
进行引入,导入成功后,会把之前指定html路径的标签全部渲染过来。
views.py如下:
from django.shortcuts import render, HttpResponse
def custom(request):
context = {
'data': 'sehun', 'name': request.GET.get('name')}
return render(request, 'custom.html', context)
xx.py如下:
from django.template import Library
register = Library()
@register.filter
def my_upper(value, k1):
return value + k1
@register.filter
def my_bool(value, k1):
if k1 != value:
return False
return True
@register.simple_tag
def my_lower(value, a1, a2, a3):
return value + a1 + a2 + a3
@register.inclusion_tag('inclusion.html')
def inclusion(value, a1, a2, a3):
data_list = [value, a1, a2, a3]
color_list = ['red', 'darkorange', 'lightskyblue']
return {
'data_list': data_list, 'color_list': color_list}
inclusion.html如下:
{% for data in data_list %}
{% if forloop.first %}
<p style="color: {
{
color_list|first}}">{
{ data }}p>
{% elif forloop.last %}
<p style="color: {
{
color_list|last}}">{
{ data }}p>
{% else %}
<p style="color: {
{
color_list.1}}">{
{ data }}p>
{% endif %}
{% endfor %}
此时访问127.0.0.1:8000/custom/如下:
可以看到在使用inclusion_tag方法指定html后,通过传值的方法,也可以使用模板语言,以及循环标签,不过在传递参数给指定html的时候需要以{“参数”:值}
形式传参,才可以搭配使用模板语言,并展示在custom.html中,且搭配使用,能让模板的结构实现优化。
在模板的结构优化方面,模板继承比引入模板的灵活性更高、应用更广。
Python中的类:
在父类中可以先定义好一些变量和方法,然后在子类中实现。
模板继承类似于Python,也可以在父模板中先定义好一些子模板需要用到的代码,然后子模板直接继承,同时因为子模板有需要自己实现的代码,因此需要在父模板中定义一个block接口,用于子模板的扩展。
base.html如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}title>
head>
{% block css %}{% endblock %}
<body>
<ul>
<li>发现li>
<li>关注li>
<li>消息li>
<li>用户:{
{ name }}li>
ul>
{% block content %}
{% endblock %}
<footer>网站底部footer>
body>
{% block js %}{% endblock %}
html>
child.html如下:
{% extends 'base.html' %}
{% block title %}子版{% endblock %}
{% block css %}{% endblock %}
<h1>母版外的子版内容h1>
{% block content %}
<h1>子版内容h1>
{% endblock %}
{% block js %}{% endblock %}
urls.py如下:
from django.urls import path
from app01 import views
urlpatterns = [
path('test/', views.test, name="test"),
path('custom/', views.custom, name="custom"),
path('child/', views.child, name='child'),
]
views.py如下:
from django.shortcuts import render, HttpResponse
def child(request):
context = {
'name': 'sehun'}
return render(request, 'child.html', context)
此时访问127.0.0.1:8000/child/如下:
显然母版被子版继承了,且母版的模板语言,也可以通过子版渲染,所以母版的使用,使代码更加整洁,重用性更加的高,能被多个子版调用,一般网页上导航条功能展示多用于充当母版使用
。当然,如果子版写的标签不在block接口中,自然不能被显示出来。