zoukankan      html  css  js  c++  java
  • Django框架之----------模板(Template)

    模板

    • 1. 模板的功能

    产生html,控制页面上展示的内容。模板文件不仅仅是一个html文件

    模板文件包含两部分内容:

    1) 静态内容css,js,html。

    2) 动态内容:用于动态去产生一些网页内容。通过模板语言来产生。

    • 2. 模板文件的使用

    通常是在视图函数中使用模板产生html内容返回给客户端。

    a) 加载模板文件 loader.get_template

    获取模板文件的内容,产生一个模板对象。

    b) 定义模板上下文 RequeseContext

    给模板文件传递数据。

    c) 模板渲染产生html页面内容 render

    用传递的数据替换相应的变量,产生一个替换后的标准的html内容。

     1 from django.shortcuts import render
     2 from django.template import loader,RequestContext
     3 from django.http import HttpResponse
     4 
     5 # Create your views here.
     6 
     7 def My_render(request,template_path,context={}):
     8     #   1、加载模板文件,获取模板对象
     9     temp = loader.get_template(template_path)
    10     #   2、定义模板上下文,给模板文件传递数据
    11     context = RequestContext(request,context)
    12     context.push(locals())
    13     #   3、模板渲染,产生一个替换后的html内容
    14     res_html = temp.render(context=locals(), request=request)
    15     #   4、返回应答
    16     return HttpResponse(res_html)
    17 
    18 def index(request):
    19     ##  调用My_render
    20     # return My_render(request,'booktest/index.html')
    21 
    22     ##  上面的4个步骤django已经封装好了,直接调用就可以了
    23     return render(request,'booktest/index.html')
    模板文件的使用
    • 3. 模板文件加载顺序

     

    1) 首先去配置的模板目录下面去找模板文件。

    2) INSTALLED_APPS下面的每个应用的templates去找模板文件,前提是应用中必须有templates文件夹。

     

    • 4. 模板语言

    模板语言简称为DTL。(Django Template Language)

    4.1 模板变量

    模板变量名是由数字,字母,下划线和点组成的,不能以下划线开头。

    使用模板变量:{{模板变量名}}

    模板变量的解析顺序:

    例如:{{ book.btitle }}

    1) 首先把book当成一个字典,把btitle当成键名,进行取值book['btitle']

    2) book当成一个对象,把btitle当成属性,进行取值book.btitle

    3) book当成一个对象,把btitle当成对象的方法,进行取值book.btitle

    例如:{{book.0}}

    1) 首先把book当成一个字典,把0当成键名,进行取值book[0]

    2) book当成一个列表,把0当成下标,进行取值book[0]

    如果解析失败,则产生内容时用空字符串填充模板变量。

    使用模板变量时,.前面的可能是一个字典,可能是一个对象,还可能是一个列表。

     1 from django.shortcuts import render
     2 from django.template import loader,RequestContext
     3 from django.http import HttpResponse
     4 from booktest.models import BookInfo
     5 
     6 
     7 def temp_var(request):
     8     '''模板变量'''
     9     dict = {'key':'这是一个字典key值'}
    10     list = ['元素1','元素2','元素3']
    11     book = BookInfo.objects.get(id=4)
    12     context = {'dict':dict,'list':list,'book':book}
    13     return render(request,'booktest/temp_var.html',context)
    视图函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <p>字典:{{ dict.key }}</p>
    <p>列表:{{ list.1 }}</p>
    <p>属性:{{book}}</p>
    
    </body>
    </html>
    模板文件

     

    4.2 模板标签

    {% 代码段 %}

    for循环:

    {% for x in 列表 %}

    # 列表不为空时执行

    {% empty %}

    # 列表为空时执行

    {% endfor %}

    可以通过{{ forloop.counter }}得到for循环遍历到了第几次。

    {% if 条件 %}

    {% elif 条件 %}

    {% else %}

    {% endif %}

    关系比较操作符:> < >= <= == !=

    注意:进行比较操作时,比较操作符两边必须有空格。

    逻辑运算:not and or

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf8">
        <title>temp_tags</title>
        <style>
            .red{
                background:red;
            }
            .yellow{
                background:yellow;
            }
            .green{
                background:green;
            }
        </style>
    </head>
    <body>
    
    <ul>
        {% for book in books %}
    
                <!--加入判断条件-->
                {% if book.id < 5 %}
                    <li class="red">
                         {{ forloop.counter }}--{{ book.btitle }}
                    </li>
                {% elif book.id < 10 %}
                    <li class="yellow">
                        {{ forloop.counter }}--{{ book.btitle }}
                    </li>
                {% else %}
                    <li class="green">
                        {{ forloop.counter }}--{{ book.btitle }}
                    </li>
                {% endif %}
    
    
        {% endfor %}
    
    
    
    </ul>
    
    
    </body>
    
    </html>
    模板标签

     

    4.3 过滤器

    过滤器用于对模板变量进行操作。

    date:改变日期的显示格式。

    length:求长度。字符串,列表.

    default:设置模板变量的默认值。

    格式:模板变量|过滤器:参数

    自定义过滤器。

    自定义的过滤器函数,至少有一个参数,最多两个

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf8">
        <title>temp_filter</title>
        <style>
            .red{
                background:red;
            }
            .yellow{
                background:yellow;
            }
            .green{
                background:green;
            }
        </style>
    </head>
    <body>
    
    <ul>
        {% for book in books %}
    
                <!--加入判断条件-->
                {% if book.id < 5 %}
                    <li class="red">
                         {{ book.btitle }}--{{ book.bpub_date|date:"Y年-m月-d日" }}
                    </li>
                {% elif book.id < 10 %}
                    <li class="yellow">
                        {{ book.btitle }}--{{ book.bpub_date }}
                    </li>
                {% else %}
                    <li class="green">
                        {{ book.btitle }}--{{ book.bpub_date }}
                    </li>
                {% endif %}
    
    
        {% endfor %}
    
    
    
    </ul>
    
    
    </body>
    
    </html>
    模板过滤器

    参考资料:(模板标签和内置过滤器)

    http://python.usyiyi.cn/documents/django_182/ref/templates/builtins.html

    4.4 模板注释

    单行注释:{# 注释内容 #}

    多行注释:

    {% comment %}

    注释内容

    {% endcomment %}

    • 5. 模板继承

    模板继承也是为了重用html页面内容。

     

    在父模板里可以定义块,使用标签:

    {% block 块名 %}

    块中间可以写内容,也可以不写

    {% endblock 块名%}

    子模板去继承父模板之后,可以重写父模板中的某一块的内容。

    继承格式:{% extends 父模板文件路径%}

    {% block 块名 %}

    {{ block.super}} #获取父模板中块的默认内容

    重写的内容

    {% endblock 块名%}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}父模板{% endblock title %}</title>
    </head>
    <body>
    <h1>导航条</h1>
    {% block a %}
        {# 给子模板预留位置 #}
        <h1>这是父模板的信息</h1>
    {% endblock a %}
    
    <h1>版权信息</h1>
    
    </body>
    </html>
    父模块
    {% extends 'booktest/base.html' %}
    {% block title %}子模板{% endblock title %}
    {% block a %}
        {# 继承父模板,重写块 #}
        {{ block.super }}
        <h1>这是子模板的信息</h1>
    {% endblock a %}
    子模块
    • 6. html转义

    在模板上下文中html标记默认是会被转义的。

    小于号< 转换为<

    大于号> 转换为>

    单引号' 转换为'

    双引号" 转换为 "

    与符号& 转换为 &

    要关闭模板上下文字符串的转义:可以使用 {{ 模板变量|safe}}

    也可以使用:

    {% autoescape off %}

    模板语言代码

    {% endautoescape %}

    模板硬编码中的字符串默认不会经过转义,如果需要转义,那需要手动进行转义。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板转义</title>
    </head>
    <p>没有进行转义:{{ context }}</p>
    
    
    <p>使用过滤器safe关闭转义:{{ context|safe }}</p>
    
    <p>使用autoescape关闭转义:</p>
    {% autoescape off %}
        {{ context }}
    {% endautoescape %}
    
    <p>模板硬编码默认会进行转义:</p>
    {{ test|default:'<h1>硬编码</h1>' }}
    
    <p>关闭模板硬编码默认转义:</p>
    {{ test|default:'&lt;h1&gt;硬编码&lt;h1&gt;' }}
    </body>
    </html>
    模板转义
    • 7. csrf攻击

    首先做一个登录页,让用户输入用户名和密码进行登录,登录成功之后跳转的修改密码页面。在修改密码页面输入新密码,点击确认按钮完成密码修改。

    登录页需要一个模板文件login.html.修改密码页面也需要一个模板文件change_pwd.html.

    显示登录页的视图login,验证登录的视图login_check,显示发帖页的视图change_pwd,处理修改密码的视图change_pwd_action.

    加功能:

    a)只有用户登录之后才可以进行修改密码操作。

    登录装饰器函数

     

    案例流程图:

     

    CSRF攻击原理

    CSRF:跨站请求伪造

    • 用户访问一个正常网站例如www.baidu.com假如用户通过post提交用户信息,服务器设置了session,会发一个sessionid给浏览器保存
    • 用户又访问了攻击者构造的恶意网站
    • 恶意网站可以让用户自动提交一个请求到目标网站(www.baidu.com),这个时候恶意网站就会将浏览器保存的sessionid发过去服务器,从而修改服务器里保存的用户信息
    • 提交请求的操作不是恶意网站发起的而是恶意网站让用户发起的

    django防止csrf的方式:

    1) 默认打开csrf中间件。

    2) 表单post提交数据时加上{% csrf_token %}标签。

    防御原理:

    1) 渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域。

    2) 服务器交给浏览器保存一个名字为csrftokencookie信息。

    3) 提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败。

     

    • 8. 验证码

    在用户注册、登录页面,为了防止暴力请求,可以加入验证码功能,如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压力。

     1 from PIL import Image, ImageDraw, ImageFont
     2 from django.utils.six import BytesIO
     3 
     4 
     5 # /verify_code
     6 def verify_code(request):
     7     # 引入随机函数模块
     8     import random
     9     # 定义变量,用于画面的背景色、宽、高 RGB
    10     bgcolor = (random.randrange(20, 100), random.randrange(
    11         20, 100), 255)
    12     width = 100
    13     height = 25
    14     # 创建画面对象
    15     im = Image.new('RGB', (width, height), bgcolor)
    16     # 创建画笔对象
    17     draw = ImageDraw.Draw(im)
    18     # 调用画笔的point()函数绘制噪点
    19     for i in range(0, 500):
    20         xy = (random.randrange(0, width), random.randrange(0, height))
    21         fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
    22         draw.point(xy, fill=fill)
    23 
    24     # 定义验证码的备选值
    25     str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
    26     # 随机选取4个值作为验证码
    27     rand_str = ''
    28     for i in range(0, 4):
    29         rand_str += str1[random.randrange(0, len(str1))]
    30 
    31     # 构造字体对象,ubuntu的字体路径为“/usr/share/fonts/truetype/freefont”
    32     font = ImageFont.truetype('static/font/verdana.ttf', 23)
    33     # 构造字体颜色
    34     fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
    35     # 绘制4个字
    36     draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
    37     draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
    38     draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    39     draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
    40     # 释放画笔
    41     del draw
    42     # 存入session,用于做进一步验证
    43     request.session['verifycode'] = rand_str
    44     # 内存文件操作
    45     buf = BytesIO()
    46     # 将图片保存在内存中,文件类型为png
    47     im.save(buf, 'png')
    48     # 将内存中的图片数据返回给客户端,MIME类型为图片png
    49     return HttpResponse(buf.getvalue(), 'image/png')
    验证码视图函数
    • 9. 反向解析

    当某一个url配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化。

    根据url 正则表达式的配置动态的生成url。

    在项目urls中包含具体应用的urls文件时指定namespace;

    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'^',include(('booktest.urls','booktest'),namespace='booktest')),
    ]

    在应用的urls中配置是指定name;

    from django.conf.urls import url
    from booktest import views
    
    urlpatterns = [
        url(r'^index$',views.index,name='index'),
       
        url(r'^url_reverse$',views.url_reverse),##  url反向解析
        url(r'^show_args/(d+)/(d+)',views.show_args,name='show_args'),##   动态捕获位置参数
        url(r'^show_kwargs/(?P<c>d+)/(?P<d>d+)',views.show_kwargs,name='show_kwargs'),##    捕获关键字参数
        url(r'^test_reverse$',views.test_reverse),##    视图函数重定向
    ]

    (1)在模板文件中使用时,格式如下:

    {% url 'namespace名字:name' %} 例如{% url 'booktest:fan2'%}

    带位置参数:

    {% url 'namespace名字:name' 参数 %} 例如{% url 'booktest:fan2' 1%}

    带关键字参数:

    {% url 'namespace名字:name' 关键字参数 %} 例如{% url 'booktest:fan2' id=1 %}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>url反向解析</title>
    </head>
    <body>
    index链接:</br>
    <a href="/index">首页</a></br>
    <p>使用url反向解析获取/index链接</p>
    <a href="{% url 'booktest:index' %}">首页</a>
    
    <p>访问/show_args/1/2:</p>
    <p><a href="/show_args/1/2">show_args/1/2</a></p>
    
    <p>动态生成/show_args/1/2</p>
    <p><a href="{% url 'booktest:show_args' 1 2 %}">show_args/1/2</a></p>
    
    <p>访问show_kwargs/1/2:</p>
    <p><a href="show_kwargs/1/2">show_kwargs/1/2</a></p>
    
    <p>动态生成show_kwargs/1/2:</p>
    <p><a href="{% url 'booktest:show_kwargs' c=1 d=2 %}">show_kwargs/1/2</a></p>
    </body>
    </html>
    模板文件--重定向

    (2)视图函数,在重定向的时候使用反向解析:

    from django.core.urlresolvers import reverse(django更新之后是:

    from django.urls import reverse

    无参数:

    reverse('namespace名字:name名字')

    如果有位置参数

    reverse('namespace名字:name名字', args = 位置参数元组)

    如果有关键字参数

    reverse('namespace名字:name名字', kwargs=字典)

     1 from django.urls import reverse
     2 def test_reverse(request):
     3     '''重定向跳转'''
     4     ##  重定向到/index
     5     # url = reverse('booktest:index')
     6 
     7     ##  重定向到/show_args/1/2
     8     # url = reverse('booktest:show_args',args=(1,2))
     9 
    10     ##  重定向到/show_kwargs/3/4
    11     url = reverse('booktest:show_kwargs',kwargs={'c':3,'d':4})
    12     return redirect(url)
    视图函数--重定向
  • 相关阅读:
    Express本地测试HTTPS
    在 WebStorm 中,配置能够识别 Vue CLI 3 创建的项目的别名 alias
    在线版本的ps
    功能强大的任务日历组件
    tree-shaking实战
    深入diff 算法
    【题解】[SHOI2001] Panda 的烦恼
    【题解】[JLOI2011]不重复数字
    「Codeforces Global Round #10」赛后个人总结
    【题解】[SCOI2004] 文本的输入
  • 原文地址:https://www.cnblogs.com/maoxinjueluo/p/12770979.html
Copyright © 2011-2022 走看看