05-模板层1——模板语法之变量的过滤器+标签

模板语法包括变量与标签

模板部分掌握变量与标签

一:变量{{ }}

深度查询:用句点符. 来完成

#比如我想取列表ls的下标为0的元素:
    <p>{{ ls.0 }}</p>

过滤器

语法

obj为变量的名字;filter_name为某一个过滤器的名字;param是相应过滤器的参数

{{ obj|filter_name:param }}

各种常见的过滤器

date
#在views.py文件中我们如果不对时间进行处理,比如直接取n值:
#那可以在模板里进行时间格式的转化
#n=datetime.datetime.now()
{{n|date:'Y-m-d'}}
default
#如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
{{value|default:'nothing'}}
length
#返回值的长度。它对字符串和列表都起作用。例如:
{{value|length}}
slice
#切片 假如value为一个字符串,找到它下标为2-5切片组成的新字符串
{{value|slice:'2:5'}}
truncatechars
#如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
#参数:要截断的字符数 
#注意结尾的'...'算三个字符,如果参数<=3,那浏览器上显示的永远是'...'
{{value|truncatechars:5}}
safe
##Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。
##为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
#views.py文件中的字符串是这样的:
    value="<a href="">点击</a>"
#那index.html中告诉浏览器正常渲染就行,最终得到的是一个a标签:
    {{value|safe}       

二、标签:{% %}:重点掌握两个:for标签与if标签

标签看起来像是这样的:

{% tag %}

标签比变量更加复杂:

一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。

一些标签需要开始和结束标签

{% tag %} 
...标签内容 ...
{% endtag %}

深度查询:用句点符. 来完成

常见的标签

for标签————掌握

遍历每一个元素

可以利用{% for obj in list reversed %}反向完成循环。
例如:遍历一个字典

{% for key,value in dic.items %}
    <p>{{key}}:{{value}}</p>
{% endfor %}
循环序号可以通过{{forloop}}显示
##forloop.counter            The current iteration of the loop (1-indexed)
##forloop.counter0           The current iteration of the loop (0-indexed)
##forloop.revcounter         The number of iterations from the end of the loop (1-indexed)
##forloop.revcounter0        The number of iterations from the end of the loop (0-indexed)
##forloop.first              True if this is the first time through the loop
##forloop.last               True if this is the last time through the loop
                    
{% for key,value in dic.items %}
    <p>{{forloop.counter0}}:{{key}}:{{value}}</p>
{% endfor %}
for ... empty

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

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

if标签————掌握

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
{% if num > 100 or num < 0 %}
    <p>无效</p>
{% elif num > 80 and num < 100 %}
    <p>优秀</p>
{% else %}
    <p>凑活吧</p>
{% endif %}

with标签

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的。
{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

csrf_token

这个标签用于跨站请求伪造保护
之前的网页中加一个form表单的submit,点击submit时如果不注释掉settings里面中间键MIDDLEWARE里含有csrf的值会有Forbidden
但是注释掉的话虽然不会有forbidden,我们无法使用django提供的内置的保护机制。

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

不注释的情况下我们可以这样做:在login.html文件里加上csrf_token就可以了:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/whw1.css">
</head>
<body>
<form action="http://127.0.0.1:8000/login/" method="post">
    {{# 注意要在form表单里面加 #}}
    {{ csrf_token }}
    
    用户名: <input type="text" name="user"  >
    密码: <input type="password" name="pwd">
    <input type="submit">
</form>

</body>
</html>
爬虫发送post请求简单模拟:
import requests

res = requests.post('http://127.0.0.1:8000/login/',data={
    'username':'chao',
    'password':'123'
})
print(res.text)
'django.middleware.csrf.CsrfViewMiddleware', 全局中间件的配置
通过它还有一种方式:装饰器的形式
from django.views.decorators.csrf import csrf_exempt,csrf_protect
#放行csrf认证,即便是全局配置了csrf认证
@csrf_exempt  
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        username = request.POST.get('username')
        print(request.POST) #<QueryDict: {'csrfmiddlewaretoken': ['OhZYiA1NHjh6ywLldzLOzy4N2OXOmHZH4tIlZvTe5ll0p6OSNUhuEgu3aOalUZoo'], 'username': ['chao']}>
        print(username)
        return HttpResponse('ok')
        
#还有一种强制保护
@csrf_protect  #强制csrf认证,即便是全局没有配置csrf认证
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        username = request.POST.get('username')
        print(request.POST) #<QueryDict: {'csrfmiddlewaretoken': ['OhZYiA1NHjh6ywLldzLOzy4N2OXOmHZH4tIlZvTe5ll0p6OSNUhuEgu3aOalUZoo'], 'username': ['chao']}>
        print(username)
        return HttpResponse('ok')

三、实例

还是以前面那个index.html文件为例

全局的urls.py

from django.contrib import admin
from django.urls import re_path,path,include

urlpatterns = [
    path('admin/',admin.site.urls),
    #分发
    re_path('^app01/',include('app01.url'))
]

app01中的url.py

from django.urls import path,re_path
from app01 import views

urlpatterns = [
    #这里的斜杠一定要加!
    re_path('^index/$',views.index),
]

app01中的views.py

from django.shortcuts import render,HttpResponse
def index(request):
    import datetime
    n = datetime.datetime.now()
    now = strftime('%Y-%m-%d %X')
    
    #变量
    name = 'wanghwqweqwasdqwe'
    list_w = [111,222,333]
    dic_w = {'w':1,'h':2}

    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    person_1 = Person('wa1',22) #自定义类对象
    person_2 = Person('wa2',23) #自定义类对象
    person_3 = Person('wa3',24) #自定义类对象
    person_list = [person_1,person_2,person_3]
        
    return render(request,'index.html',{
                'datetime':now,
                'name':name,
                'ls':list_w,
                'dic':dic_w,
                'person1_name_upper':person_1.name.upper(),
                'person_2_age':person_list[1].age,
                'n':n,
            })
            
    #这里也可以简写成locals()——字典的key值与变量名一样!——>字典的key值与value值一样!
    #return render(requset,'index.html',locals())

templates中的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    {#变量#}
    <p>{{ datetime }}</p>
    <p>{{ name }}</p>
    <p>{{ ls }}</p>
    <p>{{ ls.0 }}</p>
    <p>{{ dic }}</p>
    <p>{{ person1_name_upper }}</p>
    <p>{{ person_2_age }}</p>
    <p>{{ ls|length }}</p>
    <p>{{ name|slice:'2:5' }}</p>
    <p>{{ name|truncatechars:7 }}</p>
    <p>{{ n|date:'Y-m-d ' }}</p>

    {#标签#}
    {#遍历字典#}
    {% for key,value in dic.items %}
        <p>{{ forloop.counter0 }}:{{ key }}:{{ value }}</p>
    {% endfor %}
    {#条件判断#}
    {% if ls.0 > 200 %}
        <p>可以可以</p>
    {% elif ls.0 > 100 and ls.0 < 200  %}
        <p>呵呵哒</p>
    {% else %}
        <p>哈哈哈哈哈</p>
    {% endif %}
    
    {#自定义过滤器#}
    {% load my_tag_filter %}
    <p>{{ ls.0|multi_filter:20}}</p>
    
     <h4>自定义标签</h4>
    <p>{% simple_tag_multi 5 6 %}</p>
    {#记得给自定义的input传参#}
    <p>{% my_input 'w' 'asd' %}</p>
                    
</body>
</html>
posted on 2019-05-17 21:54  江湖乄夜雨  阅读(158)  评论(0编辑  收藏  举报