• Django-模板继承/组件/自定义标签


    一、标签tags

    for标签

    遍历每一个元素:  写个for,然后 tab键自动生成for循环的结构,循环很基础,就这么简单的用,没有什么break之类的,复杂一些的功能,你要通过js

    def get(self,request):
          lit = ["","",""]
          return render(request,"login.html",{"lit":lit})
    views
    {% for foo in lit %}
        {{ forloop.counter}} {{  foo  }}
    {% endfor %}
    html代码

    标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

    注:循环序号可以通过{{forloop}}显示,必须在循环内部用

    forloop.counter            当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
    forloop.counter0           当前循环的索引值(从0开始)
    forloop.revcounter         当前循环的倒序索引值(从1开始)
    forloop.revcounter0        当前循环的倒序索引值(从0开始)
    forloop.first              当前循环是不是第一次循环(布尔值)
    forloop.last               当前循环是不是最后一次循环(布尔值)
    forloop.parentloop         本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等

     可以利用{% for obj in list reversed %}反向完成循环。

    empty

    for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

    def get(self,request):
          lit = []
          return render(request,"login.html",{"lit":lit})
    视图函数
    {% for foo in lit reversed %}
        {{ forloop.counter}} {{  foo  }}
    {% empty %}
        sorry
    {% endfor %}
    html代码

    if标签

    {% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

    {% if num > 100 or num < 0 %}
        <p>无效</p>  <!--不满足条件,不会生成这个标签-->
    {% elif num > 80 and num < 100 %}
        <p>优秀</p>
    {% else %}  <!--也是在if标签结构里面的-->
        <p>凑活吧</p>
    {% endif %}

    当然也可以只有if和else

    {% if user_list|length > 5 %}  <!--结合过滤器来使用-->
      七座豪华SUV
    {% else %}
        黄包车
    {% endif %}

    if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。

    注意事项

        1. Django的模板语言不支持连续判断,即不支持以下写法:

    {% if a > b > c %}
    ...
    {% endif %}

        2. Django的模板语言中属性的优先级大于方法(了解)

    def xx(request):
        d = {"a": 1, "b": 2, "c": 3, "items": "100"}
        return render(request, "xx.html", {"data": d})

          如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:

    {{ data.items }}

          默认会取d的items key的值。

    二、csrf_token

    我们以post方式提交表单的时候,会报错,还记得我们在settings里面的中间件配置里面把一个csrf的防御机制给注销了啊,本身不应该注销的,而是应该学会怎么使用它,并且不让自己的操作被forbiden,通过这个东西就能搞定。

        这个标签用于跨站请求伪造保护,

        在页面的form表单里面(注意是在form表单里面)任何位置写上{% csrf_token %},这个东西模板渲染的时候替换成了<input type="hidden" name="csrfmiddlewaretoken" value="8J4z1wiUEXt0gJSN59dLMnktrXFW0hv7m4d40Mtl37D7vJZfrxLir9L3jSTDjtG8">,隐藏的,这个标签的值是个随机字符串,提交的时候,这个东西也被提交了,首先这个东西是我们后端渲染的时候给页面加上的,那么当你通过我给你的form表单提交数据的时候,你带着这个内容我就认识你,不带着,我就禁止你,因为后台我们django也存着这个东西,和你这个值相同的一个值,可以做对应验证是不是我给你的token,存储这个值的东西我们后面再学,你先知道一下就行了,就像一个我们后台给这个用户的一个通行证,如果你用户没有按照我给你的这个正常的页面来post提交表单数据,或者说你没有先去请求我这个登陆页面,而是直接模拟请求来提交数据,那么我就能知道,你这个请求是非法的,反爬虫或者恶意攻击我的网站,以后将中间件的时候我们在细说这个东西,但是现在你要明白怎么回事,明白为什么django会加这一套防御。

    <form action="/login/" method="post">
        {% csrf_token %}  # 在form表单的任意位置添加
        用户名:<input type="text" name="username">
        密码:<input type="password" name="password">
        <button>登录</button>
    </form>
    跨站请求伪造保护

    跨站请求伪造保护的几种应用:

    1、全局配置(在settings配置)

    这种配置表示给所有的post请求添加了csrf防御机制;

    2、装饰器的两种形式

    from django.views.decorators.csrf import csrf_exempt
        # 放行csrf认证,即便是全局配置了csrf认证
        @csrf_exempt
        # post请求执行的函数
        def post(self,request):
            user = request.POST.get("username")
            pwd=request.POST.get("password")
            if user=="chao" and pwd=="123":
                return render(request,"successfully.html")
            else:
                return HttpResponse("用户名密码错误")
    放行csrf认证
    from django.views.decorators.csrf import csrf_protect
        # 强制csrf认证,即便是全局没有配置csrf认证
        @csrf_protect
        # post请求执行的函数
        def post(self,request):
            user = request.POST.get("username")
            pwd=request.POST.get("password")
            if user=="chao" and pwd=="123":
                return render(request,"successfully.html")
            else:
                return HttpResponse("用户名密码错误")
    强制csrf认证

    三、模板继承

    Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 

    创建模板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            {% block style %}
            .c1{
                background-color: red;
                height: 200px;
                width: 200px;
            }
            {% endblock %}
        </style>
    </head>
    <body>
    
    <div class="c1">
        {% block content %}
        <p>这是模板</p>
        {% endblock %}
    </div>
    
    </body>
    </html>
    {% block content %}
        <p>这是模板</p>
    {% endblock %}
    
    凡是被大括号包裹的内容表示,该模板被继承后这个内容可以自定义

    继承模板:

    <!--继承模板,必须写在最上面-->
    {% extends '模板.html' %}
    
    {% block style %}
        .c1{
            background-color: yellow;
            height: 100px;
             100px;
        }
    {% endblock style %}
    
    {% block content %}
    
        <!--保留模板内容-->
         {{ block.super }}
    
        <p>继承后重写样式</p>
    
    {% endblock content %}

    根据名字指定到哪里结束,使用block.super可以保留模板内容

    • 为了更好的可读性,你也可以给你的 {% endblock %} 标签一个 名字 。例如:

    {% block content %}
    ...
    {% endblock content %}  

       在大型模版中,这个方法帮你清楚的看到哪一个  {% block %} 标签被关闭了。

    • 不能在一个模版中定义多个相同名字的 block 标签。

    四、组件

    嵌入语法:

    {% include 'navbar.html' %}

    可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。

    例如:有个如下的导航栏,nav.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .c1{
                background-color: red;
                height: 40px;
            }
        </style>
    </head>
    <body>
    
    <div class="c1">
        <div>
            <a href="">xx</a>
            <a href="">dd</a>
        </div>
    </div>
    
    </body>
    </html>

    嵌入导航栏的页面,test.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {% include 'nav.html' %}
    <h1>xxxxxxxxxx</h1>
    </body>
    </html>

    组件和插件的简单区别:

    组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等。
    
    而插件更倾向封闭某一功能方法的函数。
    
    这两者的区别在 Javascript 里区别很小,组件这个名词用得不多,一般统称插件。
    View Code

    五、自定义标签和过滤器

    自定义过滤器:

    @register.filter

    一、app01应用文件夹中创建一个叫做templatetags的文件夹;

    例如:

    二、创建视图函数并传参数

    def tags(request):
        num=100
        return render(request,"tags.html",{"num":num})
    视图函数

    三、在templatetags文件夹里创建一个py文件用于创建过滤器;

    from django import template
    # 生成模板注册器
    register = template.Library()
    
    @register.filter
    def func(v1,v2):
        """
        过滤器参数
        :param v1: 变量值
        :param v2: 过滤器参数值
        :return:
        """
        return v1*v2
    自定义过滤器

    四、在前端页面导入过滤器并放变量等待接收参数

    {% load mytag %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {{ num|func:10 }}
    </body>
    </html>
    导入过滤器

    注意:{% load mytag %} 必须放在整个html的最上面

     

    结论:也就是说num接收服务器传参数100,又经过我们自定义的过滤器进行了二次加功,最后将过滤器的返回值发送给了前端有{{返回值}}

    过滤器的参数最多只能有两个:

    想要传多个参数如下:

    页面效果:

    如果同时使用模板继承和自定义过滤器,引入顺序:

    自定义标签:

     1、2步同自定义过滤器:

    @register.simple_tag()

    为了放置XSS攻击所以在自定义标签中返回的标签在模板中渲染后还是文本

    前端页面效果:

    使用mark_safe()方法让其正常显示标签:

    页面效果:

     @register.inclusion_tag("文件名.html")

  • 相关阅读:
    echarts事件触发多次解决办法
    nginx代理出现的问题
    iframe页面之间通信
    获取当前日期的前XX天或者后XX天
    获取本月往后一年的日期月份信息
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)D. Take a Guess
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)C. Compressed Bracket Sequence
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)B. Take Your Places!
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2) A. A Variety of Operations
    centos 查看mysql数据库命令
  • 原文地址:https://www.cnblogs.com/songzhixue/p/10902629.html
Copyright © 2020-2023  润新知