• 模板自定义标签和过滤器


    一丶前情回顾

    视图函数:
    
        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等语句后,标签不可以

  • 相关阅读:
    [原创]平面机器人的避障策略思考
    做个快乐的程序员
    [知识]双音多频(DTMF)信号
    osg 关于LOD
    (3)vtkMapper
    关于坐标系,关于矩阵及线性相关和无关的关系
    osg找不到插件的解决办法
    逆风飞扬,吴仁宏
    整合qt设计师和vs2008出了点问题,记下来
    关于NodeVisitor访问者模式
  • 原文地址:https://www.cnblogs.com/qicun/p/9961819.html
Copyright © 2020-2023  润新知