Django

05-Django模板

2018-07-27  本文已影响939人  EndEvent

一、模板概述

二、定义模板

三、反向解析

- 反向解析语法
  {% url 'namespace:name' p1 p2 %}

- 项目的urls.py文件中
  url(r'^meituan/', include('app.urls', namespace='app') )

- 应用的urls.py文件中
  # 路由(带参数)  
  url(r'^goods/(\d+)/$',views.goods, name='goods'),

  # 视图函数(带参数,和url与之对应)
  def goods(request, page):
    return HttpResponse('商品列表: 第%s页' % page)
  

- 模板(带有参数的)
  <a href="{% url 'app:goods' 3 %}"> 商品列表 </a>
  <a href="{% url 'app:students' student.id %}">{{ student.s_name }}</a>

备注:
  name属性,即是给对对应的url添加一个名字;
  但是使用 name 也存在一定的问题 ,比如在同一个项目中的不同的app中 name 可能会重名;
  Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回;
  当不小心定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间;
  namespace命名空间;

反向解析场景: 正常情况下页面中设置的商品页链接地址都是goods/,而在服务器中路由如果发生一些细微的改变时,那么在页面中所有关于商品页链接地址都需要修改。为此可以使用反向解析解决此问题。

四、模板继承

五、HTML转义

六、CSRF

- 跨域请求伪造
    某些恶意网站包含链接、表单、按钮、JS,利用用户登录在浏览器中认证,从而攻击服务
- 放置CSRF
    在settings.py文件中MIDDLEWARE添加'django.middleware.csrf.CsrfViewMiddleware'
    在form表单中添加 '{% csrf_token %}'
- 例如
<form action="{% url 'app:login' %}" method="post">
    {% csrf_token %}
    <input type="text" placeholder="输入验证码" name="text"> <br>
    <input type="submit" value="验证">
</form>

在没有放置CSRF时,会报错一下错误Forbidden (403) CSRF verification failed. Request aborted. More information is available with DEBUG=True.

七、验证码

- 在用户注册、登录页面的使用使用,为了防止暴力请求,减轻服务器的压力
- 防止CSRF的一种方式

request.session.get["k1"],如果不存在则会报错,为了防止出错可以request.session.get('k1',none)

# 验证码
def verifycode(request):
    # 导入绘图模块
    from PIL import Image,ImageDraw,ImageFont
    # 导入随机函数模块
    import random
    # 文件操作
    import io

    # 定义变量,用于图片的背景色、宽、高
    # random.randrange()返回指定递增基数集合中的一个随机数
    bgcolor = (random.randrange(20,100),random.randrange(20,100),random.randrange(20,100))
    width = 100
    heigh = 50

    # 创建图片
    image = Image.new('RGB',(width,heigh),bgcolor)

    # 创建画笔对象
    draw = ImageDraw.Draw(image)

    # 调用画笔的point函数,绘制噪点
    for i in range(0,100):
        xy = (random.randrange(0,width),random.randrange(0,heigh))
        fill = (random.randrange(0,255),255,random.randrange(0,255))
        draw.point(xy,fill=fill)

    # 定义验证码的备选值
    str = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'

    # 随机选取4个值作为验证码
    rand_str = ''
    for i in range(0,4):
        rand_str += str[random.randrange(0,len(str))]

    # 构建字体对象
    # font = ImageFont.truetype(path) # 指定路径加载字体
    # font = ImageFont.load_default() # 加载一个默认的字体
    # truetype(font=None, size=10, index=0, encoding="", layout_engine=None)
    font = ImageFont.truetype('fonts/Songti.ttc',40)
    # font = ImageFont.truetype('fonts/STXINGKA.ttf',40)

    #构建字体颜色
    fontcolor1 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor2 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor3 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor4 = (255, random.randrange(0, 255), random.randrange(0, 255))

    # 绘制4个字
    # def text(self, xy, text, fill=None, font=None, anchor=None, *args, **kwargs):
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor1)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor2)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor3)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor4)

    # 释放画笔
    del draw

    # 存入session,用于验证
    request.session['verify'] = rand_str

    # 文件操作
    buff = io.BytesIO()
    # 将图片保存在内存中,文件类型png
    image.save(buff,'png')

    # 将内存中图片数据返回给客户端,MIME类型为图片类型
    # 直接是返回验证码图片
    return HttpResponse(buff.getvalue(),'image/png')

PIL(Python Imaging Library)是Python一个强大方便的图像处理库,名气也比较大,不过只支持到Python 2.7。Pillow是PIL的一个派生分支,但如今已经发展成为比PIL本身更具活力的图像处理库。目前最新版本是3.0.0。
ython 3.x 安装Pillow: pip install Pillow

# 登录操作
def verifycodefile(request):
    # 获取到session的flag标志值
    flag = request.session.get("flag", True)
    str = ''
    if flag == False:
        str = "请重新输入"

    # 清空session
    request.session.clear()

    return render(request, 'meituan/verifycodefile.html', {"flag": str})
# 登录验证
def verifycodecheck(request):
    # 输入的验证码
    # upper()转为大写
    code1 = request.POST.get('verifycode').upper()
    # session验证码
    code2 = request.session['verify'].upper()
    
    if code1 == code2:  # 验证成功
        return render(request,'meituan/success.html')
    else:   # 重新登录操作
        request.session["flag"] = False
        return redirect('/meituan/verifycodefile/')
urlpatterns=[
    url(r'^verifycode/$',views.verifycode), # 验证码测试
    url(r'^verifycodecheck/$',views.verifycodecheck),    # 验证操作
    url(r'^verifycodefile/$',views.verifycodefile),  # 带验证码登录
]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录 | 验证码测试</title>
</head>
<body>
    <!--验证码-->
    <!--默认什么都添加,就是直接显示-->


    <!--添加登录功能验证-->
    <form action="/meituan/verifycodecheck/" method="post">
        {%csrf_token%}
        <input type="text" name="verifycode" />
        <img src="/meituan/verifycode/" /> <br>
        <input type="submit" value="验证" /> <br>
        <span>{{flag}}</span>
    </form>

</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读