模板自定义标签和过滤器

一丶前情回顾

视图函数:

    request对象
         request.path  请求路径
         request.GET   GET请求数据  QueryDict  {}
         request.POST  POST请求数据 QueryDict  {}
         request.method 请求方式    "GET"   "POST"
         request.is_ajax()       是否是Ajax请求
         request.get_full_path()    包含请求数据的路径
         
    return HttpResponse("响应体字符串")
    
    render  :渲染
        render(request,"index.html")
        render(request,"index.html",{"name":name})
    
    redirect: 重定向
        两次请求

  render没有第三个参数时,直接读取文件。

  有第3个参数时,判断有没有{}语法,然后替换

  redirect是服务器向浏览器发送302指令,它是2次请求。

  form表单提交时,url变动了。因为它必然会发生一次请求!

  当form表单的action属性为空时,单击提交。它会获取当前url作为action的属性,它和当前url没有任何关系。

思考:

  假设访问的是login,login的视图函数代码为:

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

  访问页面是正常的。

  如果改为这样呢?

def login(request):
    return redirect('/login/')

   访问页面会是怎样的效果?

分析一下:

  现在直接访问login页面,看看会不会一直跳转。

  页面提示:重定向次数过多

模板:
    
    一 变量 {{}}
深度查询   .
过滤器
         {{now|date:"Y-m-d"}}
         {{file_size:filesizeformat}} 
         {{link|safe}}

    二 标签{% %}        
        1.
        {% for i in []%}
        {{forloop.counter}}
        {{forloop.last}}
        {%endfor%}
        2.
        {% if  条件%}
        <p>1111</p>
        {%elif%}
        <p>2222</p>
        {%else%}
        <p>3333</p>
        {%endif%}
with
url
        {% url '别名' 参数 %}
        {% csrf_token %}
模板

 注意:datetime也可以做格式化,比如:

def login(request):
    import datetime
    now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    return HttpResponse(now)

   访问页面输出:

   也就是说,后端可以定义格式,前端也可以定义格式,看你喜欢哪种。重点掌握if和for语法,还有csrf_token

二丶模板自定义标签和过滤器

  标签,是为了做一些功能。过滤器,是对斜杠前面的数据做过滤。

  为什么要自定义标签和过滤器? 因为自带的不够用,需要结合需求,来自定义。

  自定义标签过滤器需要执行3个步骤:

1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

2、在app中创建templatetags模块(模块名只能是templatetags)

3、创建任意 .py 文件,如:my_tags.py

  自定义过滤器

  举例:增加一个乘法过滤器

  修改settings.py中的INSTALLED_APPS,最后一行添加当前的app。

  Django开头的,都是一些自带的app。它内置在Django源码里面!

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
]
View Code

   在app01目录里面新建一个templatetags目录,目录名必须是这个!!!!!否则Django找不到

  目录里面创建my_filter_tag.py,这个py文件名,可以随便定义。内容如下:

from django import template
from django.utils.safestring import mark_safe
register=template.Library()

@register.filter
def multi_filter(x,y):
    return x*y

  注意:头部的3行,是固定写法,不能改变。

  增加@register.filter,是为了将函数转换成过滤器。函数的名字,可以自定义。修改views.py里面的index函数,内容如下:

def index(request):
    num = 100
    return render(request,'index.html',{'num':num})

  修改index.html,修改body部分

  注意:在使用自定义标签和过滤器,必须在html文件中,导入之前创建的my_filter_tag

{% load my_filter_tag %}
<p>{{ num|multi_filter:5 }}</p>

  load表示导入模块.p标签中的内容,是执行multi_filter过滤器.

  注意:它接收了2个参数.一个是num,一个是5.因为multi_filter过滤器,定义了2个形参,使用它必须传2个参数才行

  访问index页面,输出:

  是因为自定义的模块,没有导入成功,提示找不到!为啥呢?因为django项目启动时,会导入settings.py定义的模块导入,由于app01的自定义模块是启动之后加的,所以它并没有加载进去。

  重启django项目,就可以加载了。

  再次访问index,页面输出:

   如果要完成3位乘法呢?过滤器可以增加一个形参,但是index.html怎么加第3个参数呢?

  答案是,它不能加第3个参数。所以只能在后端,将参数形式修改列表,元组,字典等方式,就可以了。

  举例1:计算4*5*6

  修改index视图函数

def index(request):
    num1 = 4
    num2 = 5
    num3 = 6
    num_list = [num1,num2,num3]
    return render(request,'index.html',{'num_list':num_list})
View Code

  修改my_filter_tag.py中的过滤器

@register.filter
def multi_filter(num_list):
    res = 1
    for i in num_list:
        res*=i
    return res
View Code

  修改index.html,修改body部分

{% load my_filter_tag %}
<p>{{ num_list|multi_filter }}</p>
View Code

  访问网页,输出:

   举例1:显示a标签

  修改my_filter_tag.py文件,增加link_tag过滤器

@register.filter
def link_tag(href):
    return "<a href=%s>click</a>"%href
View Code

   修改index视图函数

def index(request):
    link = "http://www.py3study.com/"
    return render(request,'index.html',{'link':link})
View Code

   修改index.html,修改body部分

{% load my_filter_tag %}
<p>{{ link|link_tag }}</p>

   访问网页,输出:

  发现结果不是我们想要的,查看浏览器控制台,查看响应体,发现被转义了

  因为django遇到html或者js标签,会转义.它认为是不安全的!那么如何告诉它,是安全的呢?

  需要在过滤器中导入make_safe模块

  修改my_filter_tag.py文件中的link_tag过滤器,完整代码如下:

  使用make_safe方法,告诉django是安全的,不需要转义

from django import template
from django.utils.safestring import mark_safe
register=template.Library()

@register.filter
def multi_filter(num_list):
    res = 1
    for i in num_list:
        res*=i
    return res

@register.filter
def link_tag(href):
    return mark_safe("<a href=%s>click</a>" % href)
View Code

   重启django项目,因为网页有缓存,懒的清理了,所以直接重启django项目,见效快!

  再次访问

效果就出来了.

自定义标签

  标签,是为了做一些功能

  举例:4个参数的乘法运算

  修改my_filter_tag.py,增加multi_tag函数

@register.simple_tag
def multi_tag(x,y,z):
    return x*y*z

   @register.simple_tag表示将函数转换为自定义标签

   修改index.html,修改body部分

  注意:调用标签,使用{%标签过滤器名 参数1, 参数2, 参数3......%}

  参数不限,但不能放在if  for语句中

{% load my_filter_tag %}
<p>{% multi_tag 7 8 9 %}</p>

  重启django项目,访问网页,输出:

   自定义标签和自定义过滤器的区别;

  1.标签,是为了做一些功能.过滤器,是对斜杠前面的数据做过滤

  2.标签可以写任意个形参,而过滤器最大只能写2个形参.如果过滤器需要接受多个参数,需要将参数存放在列表,元组,字典等数据中.

  3.过滤器 可以在if等语句后,标签不可以

原文地址:https://www.cnblogs.com/qicun/p/9961819.html