4.登陆功能

登陆页面初步搭建

<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-xs-8 col-xs-offset-2">
            <h1 class="text-center">登陆</h1>
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" name="username" id="username" class="form-control">
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="text" name="password" id="password" class="form-control">
            </div>
            <div class="form-group">
                <label for="">验证码</label>
                <div class="row">
                    <div class="col-xs-6">
                        <input type="text" name="code" id="id_code" class="form-control">
                    </div>
                    <div class="col-xs-6">
                        {% load static %}
                        <img src="{% static '/img/default.png' %}" alt="" width="610px" height="35px">
                    </div>
                </div>
            </div>
            <input type="button" class="btn btn-success" value="登陆">
        </div>
    </div>
</div>
</body>
login.html

图片验证码

# img标签的src属性
    1.图片路径
    2.url
    3.图片的二进制数据

# 我们计算机能够输出各式各样的字体样式,内部其实是对应者一个个(.ttf结尾)的文件
https://www.zhaozi.cn/ai/2019/fontlist.php?ph=1&classid=32&softsq=%E5%85%8D%E8%B4%B9%E5%95%86%E7%94%A8

# 图片相关模块
    pip3 install pillow
    Image:生成图片
    ImageDraw:能够在图片上乱涂乱画
    ImageFont:控制字体样式
  from PIL import Image,ImageDraw,ImageFont

# 内存管理器模块
    BytesIO:临时帮你存储数据 返回的时候数据是二进制
    StringIO:临时帮你存储数据 返回的时候数据是字符串
  from io import BytesIO,StringIO

需要将图片的src属性更改 

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

urlpatterns = [
    path('admin/', admin.site.urls),
    # 登陆功能
    re_path(r'^login/', views.login, name='login'),
    # 图片验证码相关操作
    re_path(r'^get_code/', views.get_code, name='get_code')
]
urls.py
def login(request):
    return render(request,'login.html')

'''
图片相关的模块
    pip3 install pillow
    Image:能够帮你生成图片
    ImageDraw:能够在图片上乱涂乱画
    ImageFont:能够控制字体样式
'''
from PIL import Image,ImageDraw,ImageFont
from io import BytesIO,StringIO
'''
内存管理模块
BytesIO:临时帮你存储数据,返回的时候数据是二进制
StringIO:临时帮你存储数据,返回的时候数据是字符串
'''
import random
def get_random():
    return random.randint(0,255),random.randint(0,255),random.randint(0,255)
def get_code(request):
    # # 推导步骤1:直接获取后端现成的图片二进制数据发送给前端
    # with open(r'static/img/111.png','rb') as f:
    #     data = f.read()
    # return HttpResponse(data)

    # 推导步骤2:利用pillow模块动态产生图片
    # img_obj = Image.new('RGB',(610,35),'green')
    # img_obj = Image.new('RGB',(610,35),get_random())
    # # 先将图片对象保存起来
    # with open('xxx.png','wb') as f:
    #     img_obj.save(f,'png')
    # # 再将图片对象读取出来
    # with open('xxx.png','rb') as f:
    #     data = f.read()
    #     print(data)
    # return HttpResponse(data)

    # 推导步骤3:文件存储繁琐IO效率低,借助于内存管理器
    # img_obj = Image.new('RGB',(610,35),get_random())
    # io_obj = BytesIO()  # 生成一个内存管理对象,可以看成是文件句柄
    # img_obj.save(io_obj,'png')
    # return HttpResponse(io_obj.getvalue())  # 从内存管理器中读取二进制的图片返回给前端

    # 推导步骤4:些图片验证码
    img_obj = Image.new('RGB',(610,35),get_random())
    img_draw = ImageDraw.Draw(img_obj)  # 产生一个画笔对象
    img_font = ImageFont.truetype('static/font/111.ttf',30)  # 字体样式 字体大小

    # 随机验证码(五位数字的随机验证码,数字、小写字母、大写字母)
    code = ''
    for i in range(5):
        random_upper = chr(random.randint(65,90))
        random_lower = chr(random.randint(97,122))
        random_int = str(random.randint(0,9))
        # 从上面三个里面随机选择一个
        tmp = random.choice([random_upper,random_lower,random_int])
        # 将产生的随机字符串写到图片上
        '''
        为什么一个一个写而不是生成好之后再写
        因为一个个写能够控制每个字体的间隙,而生成好之后再写的话,间隙就没法控制
        '''
        img_draw.text((i*100+100,-2),tmp,get_random(),img_font)
        # 拼接随机字符串
        code += tmp
    print(code)
    # 随机验证码在登陆的视图函数里面需要用到,要对比,所以要找地方存起来并且其他视图函数也能拿到
    request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj, 'png')
    return HttpResponse(io_obj.getvalue())
views.py

每次重新加载一次图片会在路由后面加上一个”?“

<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-xs-8 col-xs-offset-2">
            <h1 class="text-center">登陆</h1>
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" name="username" id="username" class="form-control">
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="text" name="password" id="password" class="form-control">
            </div>
            <div class="form-group">
                <label for="">验证码</label>
                <div class="row">
                    <div class="col-xs-6">
                        <input type="text" name="code" id="id_code" class="form-control">
                    </div>
                    <div class="col-xs-6">
                        {% load static %}
                        <img src="/get_code/" alt="" width="610px" height="35px" id="id_img">
                    </div>
                </div>
            </div>
            <input type="button" class="btn btn-success" value="登陆">
        </div>
    </div>
</div>

<script>
    $("#id_img").click(function () {
        // 1 先获取标签之前的src
        let oldVal = $(this).attr('src');
        $(this).attr('src',oldVal += '?')
    })
</script>
</body>
login.html

登陆功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-xs-8 col-xs-offset-2">
            <h1 class="text-center">登陆</h1>
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" name="username" id="username" class="form-control">
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="text" name="password" id="password" class="form-control">
            </div>
            <div class="form-group">
                <label for="">验证码</label>
                <div class="row">
                    <div class="col-xs-6">
                        <input type="text" name="code" id="id_code" class="form-control">
                    </div>
                    <div class="col-xs-6">
                        {% load static %}
                        <img src="/get_code/" alt="" width="610px" height="35px" id="id_img">
                    </div>
                </div>
            </div>
            <input type="button" class="btn btn-success" value="登陆" id="id_commit">
            <span style="color: red" id="error"></span>
        </div>
    </div>
</div>

<script>
    $("#id_img").click(function () {
        // 1 先获取标签之前的src
        let oldVal = $(this).attr('src');
        $(this).attr('src',oldVal += '?')
    })

    // 点击按钮发送ajax请求
    $('#id_commit').click(function(){
        $.ajax({
            url:'',
            type:'post',
            data:{
                'username':$('#username').val(),
                'password':$('#password').val(),
                'code':$('#id_code').val(),
                // 结合需求合理选择
                'csrfmiddlewaretoken':'{{ csrf_token }}'
            },
            success:function (args){
                if (args.code == 1000){
                    // 跳转到首页
                    window.location.href = args.url
                }else{
                    // 渲染错误信息
                    $('#error').text(args.msg)
                }
            }
        })
    })
</script>
</body>
</html>
login.html
# 1.先校验验证码是否正确(忽略大小写:将其同一转成大写或小写比较)
def login(request):
    if request.method == 'POST':
        back_dic = {'code':1000,'msg':''}
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')
        # 1 先校验验证码是否正确      自己决定是否忽略            统一转大写或者小写再比较
        if request.session.get('code').upper() == code.upper():
            # 2 校验用户名和密码是否正确
            user_obj = auth.authenticate(request,username=username,password=password)
            if user_obj:
                # 保存用户状态
                auth.login(request,user_obj)
                back_dic['url'] = '/home/'
            else:
                back_dic['code'] = 2000
                back_dic['msg'] = '用户名或密码错误'
        else:
            back_dic['code'] = 3000
            back_dic['msg'] = '验证码错误'
        return JsonResponse(back_dic)
    return render(request,'login.html')
views.py

 

posted @ 2023-04-03 23:47  猿小姜  阅读(14)  评论(0编辑  收藏  举报