首页 > 其他分享 >12- 登陆页面

12- 登陆页面

时间:2023-02-01 11:56:03浏览次数:39  
标签:code return form randint random request 12 登陆 页面

1. 创建url (项目 / url.py)

from app01.views import login

urlpatterns = [
# 登陆页面
    path("login/", account.login),
    path("logout/", account.logout),
    path("image/code/", account.image_code),
]

2. 创建图片验证码工具类(app01 / utils / code.py)

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter


def check_code(width=120, height=30, char_length=5, font_file="Monaco.ttf", font_size=20):
    code = []
    # 创建一张图片
    img = Image.new(mode="RGB", size=(width, height), color=(255, 255, 255))

    # 创建一个画笔
    draw = ImageDraw.Draw(img, mode="RGB")

    def rndChar():
        """生成随机字母"""
        # return chr(random.randint(65, 90))

        """随机数字"""
        return str(random.randint(0, 9))

    def rndColor():
        """随机生成颜色"""
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

    # 写文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

    # 写干扰线
    for i in range(5):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)
        draw.line((x1, y1, x2, y2), fill=rndColor())

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, "".join(code)

3. 创建视图函数(app01 / views /login.py)

from django import forms
from django.http import HttpResponse
from django.shortcuts import render, redirect

# 使用form组件做登陆
from app01 import models
from app01.utils.bootstrap import BootStrapForm
from app01.utils.encrypt import md5
from app01.utils.code import check_code


class LoginForm(BootStrapForm):
    # form需要自定义字段
    username = forms.CharField(label="用户名",
                               widget=forms.TextInput,
                               required=True)
    password = forms.CharField(label="密码",
                               widget=forms.PasswordInput(render_value=True),  # render_value=True:在输入框保留用户输入的内容
                               required=True)  # required=True: 必填
    code = forms.CharField(label="验证码",
                           widget=forms.TextInput,  # render_value=True:在输入框保留用户输入的内容
                           required=True)  # required=True: 必填

    # 定义一个钩子方法获取密码
    def clean_password(self):
        pwd = self.cleaned_data.get("password")  # cleaned_data获取用户输入的内容: {'username': '123', 'password': '321'}
        # {'username': '123', 'password': '933912614eaae2d0c86099673e398b0b'}
        return md5(pwd)  # 返回给前端结果

# # 使用modelfprm
# class LoginModelForm(forms.ModelForm):
#     class Meta:
#         # 直接去数据库里拿数据
#         model = models.Admin
#         fields = ["username", "password"]
def login(request):
    """登陆"""
    if request.method == "GET":
        form = LoginForm()
        return render(request, "login.html", {"form": form})
    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 验证成功,获取到用户名和密码
        # {'username': '123', 'password': '321',"code":"xxx"}
        # print(form.cleaned_data)  # form验证通过后只能form.cleaned_data验证

        # 验证码效验,获取到剔除的验证码
        user_input_code = form.cleaned_data.pop("code")
        code = request.session.get("image_code", "")
        print("=========", user_input_code, code)
        if code.upper() != user_input_code.upper():
            form.add_error("code", "验证码错误")
            return render(request, "login.html", {"form": form})

        # 去数据库效验用户名和密码是否正确,获取用户对象,如果错的就是None
        # admin_object=models.Admin.objects.filter(username="form.cleaned_data["username]",password="form.cleaned_data["password]").first()
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            # form / modelform可以 主动的 手动添加错误信息,(字段名,错误信息)
            form.add_error("password", "用户名或密码错误")
            # form.add_error("username", "用户名或密码错误")

            return render(request, "login.html", {"form": form})

        # 用户名和密码输入正确
        # 网站生成随机字符串,写到用户浏览器的cookie中,在写入到session中
        request.session["info"] = {"id": admin_object.id, "name": admin_object.username}  # 会自动生成cookie和在服务器生成session
        request.session.set_expiry(60 * 60 * 24 * 7)  # 7天免登录

        return redirect("/admin/list/")

    return render(request, "login.html", {"form": form})

from io import BytesIO  # 导入内存文件操作


def image_code(request):
    """生成验证图片"""

    # 调用pillow函数,生成图片,img: 图片 ;code_string: 验证码内容
    img, code_string = check_code()
    # print("code_string=", code_string)

    # 写入到自己的session中(以便于后续获取验证码在进行效验)
    request.session["image_code"] = code_string
    # 给验证码的 session设置60秒超时
    request.session.set_expiry(60)

    stream = BytesIO()  # 创建实例对象
    img.save(stream, "png")  # 将图片保存到内存中

    return HttpResponse(stream.getvalue())  # 再从内存中获取图片


def logout(request):
    """注销"""
    # 清除当前session
    request.session.clear()

    return redirect("/login/")

4. 创建html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .account{
            width:400px;
            border: 1px solid #dddddd;
            border-radius: 5px;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top:100px;
            padding: 20px 40px;
        }
        .account h2{
            margin-top:10px;
            text-align:center
        }







    </style>
</head>
<body>

<div class="account">
    <h2>用户登录</h2>
    <form method="post" novalidate>
        {% csrf_token %}
        <div class="form-group">
            <label>用户名</label>
            {{ form.username }}
            <span style="color:red;">{{ form.username.errors.0 }}</span>
        </div>

        <div class="form-group">
            <label>密码</label>
            {{ form.password }}
            <span style="color:red;">{{ form.password.errors.0 }}</span>

        </div>
        <div class="form-group">
            <label>图片验证码</label>
            <div class="row">
                <div class="col-xs-7">
                    {{ form.code }}
                    <span style="color:red;">{{ form.code.errors.0 }}</span>
                </div>
                <div class="col-xs-5">
                    <img id="image_code" src="/image/code/" style="width:125px;">
                </div>
            </div>
        </div>

        <input type="submit" value="登 陆" class="btn btn-primary">
    </form>

</div>

</body>
</html>

标签:code,return,form,randint,random,request,12,登陆,页面
From: https://www.cnblogs.com/kh-1314/p/17009994.html

相关文章

  • Educational Codeforces Round 126 (Rated for Div. 2) D. Progressions Covering(贪心
    题目https://codeforces.com/problemset/problem/1661/D题意给一个长度为n的数组a,和一个正数k,每次在数组a中选取连续的k个元素每个元素减去1,2,3……k问至少要......
  • selenium源码通读·12 |webdriver/remote分析
    (·12|webdriver/remote分析)1源码路径selenium/webdriver/remote2功能说明方法描述说明command.pyDefinesconstantsforthestandardWebDrivercom......
  • 12_3D数据
    importmatplotlib.pyplotaspltimportnumpyasnpfrommpl_toolkits.mplot3dimportAxes3Dfig=plt.figure()ax=Axes3D(fig)X=np.arange(-4,4,0.25)Y=np......
  • Educational Codeforces Round 126 (Rated for Div. 2) C. Water the Trees (从答案方
    题目https://codeforces.com/contest/1661/problem/C代码#include<bits/stdc++.h>#definedebug1(a)cout<<#a<<'='<<a<<endl;#definedebug2(a,b)cout<<#a<<"......
  • SqlServer2012 AlwaysOn部署
    一环境准备1软件准备(1)SQLServer2012企业版(2)WindowsServer20122IP准备IP作用172.16.100.115域服务器IP172.16.100.117数据库服务器IP172.16.100.118数据库服务器IP......
  • 20230129 T1 生日蛋糕(birth)
    生日蛋糕(birth)伤心题。。。题意\(n\)个点的树,第\(i\)个点有点权\(1\lea_i\lem\)。对于每个\(i\)满足\(1\lei\lem\),求出连通块内点权最大值为\(i\)的个......
  • Oracle登录和报错:ORA-12560: TNS: 协议适配器错误
    网络上的解决办法1,查看Oracle的服务是否开启2,查看监听器是否开启3,在注册表中去查看Oracle_sid的值是否有误Oracle_sid的值查看方法::在windows平台如下操作......
  • 微信注册页面密码的测试用例编写
    要求: 6~18位且由数字和字母组成,注册成功,跳转页面;注册失败,请重新输入密码1.画思维导图   2.excel编写测试用例 ......
  • 静默安装oracle 12c时报错INS-35178
    问题描述:静默安装oracle12c时报错INS-35178,如下所示:图形界面告警如下:配置文件中数据库内存管理选项如下所示:异常原因:物理内存大于4G不能用AMM,只能使用ASMM.解决方案:将配......
  • 小程序页面的生命周期
    #####4.6页面的生命周期#####问题-页面的生命周期函数都有哪些?1.每个小程序页面,必须拥有自己的`.js`文件,且必须调用`Page()`函数,否则报错。其中`Page()`......