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;
        width: 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")

 

posted @ 2019-05-21 21:47  叫我大表哥  阅读(493)  评论(0编辑  收藏  举报