Django--实战--1--登录模块

所涉及知识点

  • 一次请求伴随多次请求
  • PIL
  • session存储
  • 验证码局部刷新,使用src =+ “?”,不需要使用ajax
  • ajax发送验证信息

1 路由配置

# urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('index/', views.index),
    path('get_validCode_img/', views.get_validCode_img)
]

2 login.html

<!-- login.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css">
</head>
<body>
<h3>登录页面</h3>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-lg-3">
            <form>
                {% csrf_token %}
                <div class="form-group">
                    <label for="user">用户名</label>
                    <input type="text" id="user" class="form-control">
                </div>
                <div class="form-group">
                    <label for="pwd">密码</label>
                    <input type="password" id="pwd" class="form-control">
                </div>
                <div class="form-group">
                    <label for="">验证码</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" id="valid_code" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <img id="valid_code_img" width="115" height="35" src="/get_validCode_img/" alt="">
                        </div>
                    </div>
                </div>

                <input type="button" class="btn btn-default login_btn" value="submit"><span class="error"></span>
            </form>
        </div>
    </div>
</div>

<script src="/static/js/jquery-3.6.0.min.js"></script>
<script>
    // 刷新验证码
    $("#valid_code_img").click(function () {
        $(this)[0].src+="?"
    })
    
    $(".login_btn").click(function () {
        $.ajax({
            url:"",  // 不加默认还是当前网址
            type:"post",
            data:{
                user:$("#user").val(),
                pwd:$("#pwd").val(),
                valid_code:$("#valid_code").val(),
                csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
            },
            success:function (data) {
                console.log(data)

                if (data.user){
                    location.href="/index/"
                }
                else {
                    $(".error").text(data.msg).css({"color":"red", "margin-left":"10px"})
                    setTimeout(function () {
                        $(".error").text("")
                    }, 1000)
                }
            }
        })

    })
</script>
</body>
</html>

3 validCode.py

validCode.py模块用于生成验证码图片,在相应app(此处是blog)下建立一个utils工具包,并在其下建立一个validCode.py文件

# validCode.py
import random


def get_random_color():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)


def get_valid_code_img(request):

    from PIL import Image, ImageDraw, ImageFont
    from io import BytesIO

    img = Image.new('RGB', (115, 35), color=get_random_color())  # 构建img对象
    draw = ImageDraw.Draw(img)  # 构建绘画对象
    iNkedGod_font = ImageFont.truetype('static/font/iNkedGod.ttf', size=20)  # 构建字体对象

    valid_code_str = ''
    for i in range(5):
        random_num = str(random.randint(0, 9))
        random_low_alpha = chr(random.randint(95, 122))
        random_upper_alpha = chr(random.randint(65, 90))
        random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])  # 生成随机字符
        draw.text((i * 20 + 10, 5), random_char, get_random_color(), font=iNkedGod_font)  # 在img上写文字

        # 保存验证码
        valid_code_str += random_char
    # width, height = 115, 35
    # for i in range(8):  # 画噪线
    #     x1, y1 = random.randint(0, width), random.randint(0, height)
    #     x2, y2 = random.randint(0, width), random.randint(0, height)
    #     draw.line((x1, y1, x2, y2), fill=get_random_color())
    #
    # for i in range(20):
    #     draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())  # 画噪点
    #     x, y = random.randint(0, width), random.randint(0, height)
    #     draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())  # 画噪弧

    print("valid_code_str", valid_code_str)

    request.session["valid_code_str"] = valid_code_str
    """
    1 生成随机字符串asf12dfaf565asdfafd
    2 为COOKIE增加一个字段{"sessionID": "asf12dfaf565asdfafd"}
    3 在django-session中增加一行
      session-key           session-data
      asf12dfaf565asdfafd   {"valid_code_str":"12345"}
    """

    f = BytesIO()  # 内存字节对象
    img.save(f, "png")  # 保存到内存
    data = f.getvalue()  # 从f对象读数据
    return data

4 编写login视图函数

# views.py
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from django.contrib import auth


def login(request):
    if request.method == "POST":

        response = {"user": None, "msg": None}
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        valid_code = request.POST.get("valid_code")

        # 自动根据cookie中的sessionID字段从django的session表中查询到相应的session信息,再从相应的session中拿到valid_code_str
        valid_code_str = request.session.get("valid_code_str")
        print("user", user)
        print(valid_code, valid_code_str)
        if valid_code.upper() == valid_code_str.upper():  # 使用upper()使得验证码不区分大小写

            # authenticate去auth_user查询记录,查询成功返回用户对象,查询失败返回None
            user = auth.authenticate(username=user, password=pwd)
            if user:
                # 保存用户状态信息(保存到session中)
                # 等价于request.session['key'] = User_obj
                # 执行该方法后,就可以通过request.user来获取当前登陆的用户对象
                auth.login(request, user)

                response["user"] = user.username
            else:
                response["msg"] = "用户名或者密码错误"
        else:
            response["msg"] = "验证码错误"
        return JsonResponse(response)
    return render(request, 'login.html')


def index(request):

    return render(request, "index.html")


def get_validCode_img(request):
    """
    生成验证码
    :param request:
    :return:
    """
    from blog.utils.validCode import get_valid_code_img
    data = get_valid_code_img(request)
    return HttpResponse(data)

5 总结

后端任务:接受前端发送来的登录者的登录信息,验证通过将用户状态保存进session并向前端返回登录成功的信息;验证不通过向前端返回具体的错误信息。

前端任务:通过ajax向后端发送登录者的登录信息,并接受相应的响应信息。若是成功信息直接跳转到首页;若是失败信息需将失败信息渲染到页面以提醒登录者。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值