首页 > 其他分享 >bbs 注册登录 验证

bbs 注册登录 验证

时间:2023-12-10 15:01:14浏览次数:32  
标签:username 登录 form 验证 bbs 校验 length data id

注册页面
-用户名
-密码
-确认密码
-邮箱
-手机号
-头像


# form组件 可以帮助我们
1 快速生成前端页面
2 数据校验
3 错误处理


# 如何使用
-1 写一个类,继承forms.Form
-2 在类中写属性和方法
-属性:要跟咱们要校验或自动生成页面的字段一一对应
-方法:对字段进行校验:
clean_字段名 给单个字段校验
clean 给多个字段校验
-3 在视图函数中使用
-4 模板中使用



# form表单中,如果定义了button或input 类型是"submit",只要点击,就会默认触发form表单的提交,如果我们又写了ajax提交,就会触发两次---》导致问题-
-把它搞外面
-input 类型是"button"

from django import forms
from django.forms import widgets, ValidationError
from .models import UserInfo


class RegisterForm(forms.Form):
    # max_length=18 最长 18
    # min_length=3 最短 3
    # required=True 必填
    username = forms.CharField(max_length=18, min_length=3, required=True,
                               label='用户名',
                               error_messages={
                                   'required': '用户名字段必填',
                                   'max_length': '长度不能超过18',
                                   'min_length': '最短3'
                               }, widget=widgets.TextInput(attrs={'class': 'form-control'}))

    password = forms.CharField(max_length=18, min_length=3, required=True,
                               label='密码',
                               error_messages={
                                   'required': '用户名字段必填',
                                   'max_length': '长度不能超过18',
                                   'min_length': '最短3'
                               }, widget=widgets.PasswordInput(attrs={'class': 'form-control'}))

    re_password = forms.CharField(max_length=18, min_length=3, required=True,
                                  label='确认密码',
                                  error_messages={
                                      'required': '用户名字段必填',
                                      'max_length': '长度不能超过18',
                                      'min_length': '最短3'
                                  }, widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(max_length=18, min_length=3, required=True,
                             label='邮箱',
                             error_messages={
                                 'required': '用户名字段必填',
                                 'max_length': '长度不能超过18',
                                 'min_length': '最短3'
                             }, widget=widgets.EmailInput(attrs={'class': 'form-control'}))
    phone = forms.CharField(max_length=11, min_length=11, required=True,
                            label='手机号',
                            error_messages={
                                'required': '用户名字段必填',
                                'max_length': '长度不能超过11',
                                'min_length': '必须11为'
                            }, widget=widgets.TextInput(attrs={'class': 'form-control'}))

    # 方法名只能写两类
    # 一类是  clean_字段名  校验单个字段
    def clean_username(self):  # 如果能走到这里,说明上面的校验已经通过了,校验过后的数据都放在一个字典中---》cleaned_data
        username = self.cleaned_data.get('username')
        # 用户名不能以sb开头
        if username.startswith('sb'):
            # 校验不通过,抛异常
            raise ValidationError('名字不能以sb开头')
        # 如果用户名存在,也不能注册了
        res = UserInfo.objects.filter(username=username).exists()
        if res:
            raise ValidationError('该用户已经存在')
        return username

    # 二类是  clean   同时校验多个字段
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if not password == re_password:
            raise ValidationError('两次密码不一致')
        return self.cleaned_data

  

注册功能前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/js/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>

<div class="container-fluid">


    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1 class="text-center">注册功能</h1>
            <form id="register_form">
                {% csrf_token %}
                {% for foo in form %}
                    <div class="form-group">
                        <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
                        {{ foo }} <span class="pull-right error" style="color: red"></span>
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="id_avatar">头像
                        <img src="/static/img/default.png" alt="" height="80px" width="80px" id="id_img"
                             style="margin-left: 20px">

                    </label>
                    <input type="file" id="id_avatar" class="form-control" accept="image/*" style="display: none">
                </div>
                <div class="text-center">
                    <input type="button" value="注册" class="btn btn-danger" id="id_submit">
                    <span class="error" style="color: darkred;margin-left: 10px" id="id_error"></span>
                </div>


            </form>
        </div>
    </div>
</div>

</body>

<script>
    // 1 监控文件变化
    $('#id_avatar').change(function () {
        // 读出input 的图片,写到 img标签上
        // 需要借助于文件阅读器
        var fileReader = new FileReader();
        // 把文件对象读入文件阅读器中
        fileReader.readAsDataURL($('#id_avatar')[0].files[0])
        // 等文件读完,再放入
        fileReader.onload = function () {
            //$('#id_img').attr('height', '300px')
            $('#id_img').attr('src', fileReader.result)
            //$('#id_img')[0].src = fileReader.result
        }


    })


    // 2 按钮提交---》注册功能
    $('#id_submit').click(function () {

        var formdata = new FormData()
        // 把文件放入
        formdata.append('my_img', $('#id_avatar')[0].files[0])

  

//放数据:用户名,密码,确认密码,手机号,邮箱 ,你可以一个个放--->

笨办法
/*
formdata.append('username', $('#id_username').val())
formdata.append('password', $('#id_password').val())
formdata.append('re_password', $('#id_re_password').val())
formdata.append('phone', $('#id_phone').val())
formdata.append('email', $('#id_email').val())
formdata.append('csrfmiddlewaretoken', '

{{ csrf_token }}') // csrf 的token
*/

 

简单方案
        var register_form = $('#register_form').serializeArray() // 会把当前form表单中得数据放到列表套字典的形式
        /*
        数组
        [{name:xx,value:yy}, {…}, {…}, {…}, {…}]
        */
        //console.log(register_form)
        // jq 的循环
        $.each(register_form, function (i, v) {
            //console.log(v['name'])
            //console.log(v['value'])
            formdata.append(v['name'], v['value'])
        })

        $.ajax({
            url: '/register/',
            method: 'post',
            processData: false,
            contentType: false,
            data: formdata,
            success: function (data) {
                if (data.code == 100) {
                    location.href = '/login/'
                } else { // 不成功
                    // 两次密码不一致,把错误写在 注册按钮后面
                    // input 自己的错误,写在自己后面
                    // 循环返回的错误
                    $.each(data.errors, function (key, value) {
                        if (key == '__all__') {
                            $('#id_error').html(value[0])
                        }
                        $('#id_' + key).next().html(value[0]).parent().addClass('has-error')

                    })


                    // 过3s后,清空错误,和红框
                    setTimeout(function () {
                        $('.error').html("").parent().removeClass('has-error')
                        //alert('asfdsdaf')
                    }, 3000)


                }
            }
        })


    })

  

 3 当用户名输入框失去焦点,我们就去后端校验用户名是否注册过
    $('#id_username').blur(function () {
        //alert('失去焦点了')
        //var username=$('#id_username').val()
        var username = $(this).val()
        $.ajax({
            url: '/check_username/?username=' + username,
            method: 'get',
            success: function (data) {
                console.log(data)
                if (data.code != 100) {
                    // 1 清空输入框
                    //$(this).val()
                    // 2 错误提示
                    //$(this).next().html(data.msg)
                    console.log('ssss')
                    // 两句可以并做一句---》链式调用
                    // 如果在另一个内部函数中,就不能用this
                    //var ss=$('#id_username').val()
                    //$('#id_username').next().html(data.msg).parent().addClass('has-error').children('input').val("")
                    $('#id_username').val('').next().html(data.msg).parent().addClass('has-error')

                }
            }
        })
    })

</script>
</html>

 

注册功能后端

 

from django.shortcuts import render
from .forms import RegisterForm
from .models import UserInfo
from django.http import JsonResponse


# Create your views here.
def register(request):
    if request.method == 'GET':
        form = RegisterForm()
        return render(request, 'register.html', {'form': form})
    else:
        # # 1 数据
        # print(request.POST)
        # # 2 文件
        # print(request.FILES.get('my_img'))
        # 取出头像
        avatar = request.FILES.get('my_img')
        # 校验数据是否合法
        '''
        username: admin
        password: 123
        email: [email protected]
        phone: 17717823244
        avatar:文件
        '''
        form = RegisterForm(request.POST)  # 使用form校验传入的数据
        if form.is_valid():  # 校验通过
            # 保存
            data = form.cleaned_data
            # 把re_password 弹出
            data.pop('re_password')
            # 把头像加入
            if avatar:
                data['avatar'] = avatar
            UserInfo.objects.create_user(**data)
            return JsonResponse({'code': 100, 'msg': '注册成功'})
        else:
            return JsonResponse({'code': 101, 'msg': '注册失败', 'errors': form.errors})


# 校验用户名是否存在的接口
def check_username(request):
    username = request.GET.get('username')
    res = UserInfo.objects.filter(username=username).exists()
    if res:
        # 约定状态码:100,表示成功,非100表示失败
        return JsonResponse({'code': 101, 'msg': '用户已经存在'})
    else:
        return JsonResponse({'code': 100, 'msg': '您可以注册'})

  

forms组件
-1 渲染模板
-2 校验数据
-3 渲染错误
- form=RegisterForm()---渲染页面
- form=RegisterForm(requets.POST)---校验数据
# 2 取数据,取文件
-form-data提交数据
-request.POST 中取数据
-request.FILES.get('名字') 取文件
-补:前端是key:value 后端变成了 key:[value]
-request.data 不是真正的字典
{'username': ['admin','xxx'], 'password': ['123']}
request.POST.get('username')
request.POST.getlist('username')

# 3 保存 文件和数据
# data 是form校验过后的数据,没有头像
data.pop('re_password') # 不是表的字段
# 把头像加入 头像是表的字段
if avatar:
data['avatar'] = avatar # 文件对象
# avatar = models.ImageField(upload_to='avatar', default='avatar/default.png')
内部自动:打开一个空文件,把文件写入到空文件中 【/media/avatar/】,并且把路径赋值给avatar数据库字段
UserInfo.objects.create_user(**data)


# 4 前端:头像实时显示
-隐藏了 input file---》input只能接收图片类型
-只要input发生变化(change)---》把图片读出来,写入到 img标签中
var fileReader = new FileReader();
fileReader.readAsDataURL($('#id_avatar')[0].files[0])
fileReader.onload = function () {
$('#id_img').attr('src', fileReader.result)
}



# 5 用户名失去焦点(blur)---》向后端校验

# 6 form表单使用var register_form = $('#register_form').serializeArray() 转到数组中

# 7 $.each(可以被循环的,function(){})

# 8 错误信息渲染
-__all__ 全局错误---》显示在注册后面
if (key == '__all__') {
$('#id_error').html(value[0])
}
-其他错误,显示在自己后面
$('#id_' + key).next().html(value[0]).parent().addClass('has-error')

-定时任务:3s后干什么
setTimeout(function () {
$('.error').html("").parent().removeClass('has-error')
}, 3000)

 

登录功能

 登录前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/js/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>

<div class="container-fluid">


    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1 class="text-center">登录功能</h1>
            <form>
                <div class="form-group">
                    <label for="">用户名</label>
                    <input type="text" name="username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="">密码</label>
                    <input type="text" name="password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="">验证码</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" name="code" class="form-control">
                        </div>

                        <img src="/get_code/" alt="" class="col-md-6" height="35">
                    </div>
                </div>
                <div class="text-center" style="margin-top: 50px">
                    <input type="button" value="登录" class="btn btn-danger" id="id_submit">
                    <span class="error" style="color: darkred;margin-left: 10px" id="id_error"></span>
                </div>
            </form>
        </div>
    </div>
</div>

</body>

</html>

  

生成验证码

第三方方案
https://pythonjishu.com/ljpdvvedzkqiovs/

# 自己的方案

 

def get_code(request):
    # 前端显示图片 方式一
    # with open('./static/img/4.jpg', 'rb') as f:
    #     data = f.read()
    # return HttpResponse(data)

    # 方式二:自己生成一张图片,保存到本地-->打开,返回给前端
    # image_tmp = Image.new('RGB', (300, 38), (255, 255, 0))
    #
    # with open('code.png', 'wb') as f:
    #     image_tmp.save(f, 'png')
    #
    # with open('code.png', 'rb') as f:
    #     data = f.read()
    # return HttpResponse(data)

    # 方式三:借助于ByteIo,把文件内容放在内存中
    # image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))
    # # 放在内存中
    # my_io = BytesIO()
    # image_tmp.save(my_io, 'png')
    # return HttpResponse(my_io.getvalue())

    # 方式四: 要在图片上写文字
    # image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))
    # # 把空图片放在了画板上
    # draw = ImageDraw.Draw(image_tmp)
    # draw.text((0, 0), 'lqz')
    # my_io = BytesIO()
    # image_tmp.save(my_io, 'png')
    # return HttpResponse(my_io.getvalue())

    # 方式5 :加入字体文件
    # image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))
    # # 把空图片放在了画板上
    # draw = ImageDraw.Draw(image_tmp)
    # # 加入字体
    # img_font = ImageFont.truetype('./static/font/xgdl.ttf', 23)
    # draw.text((0, 0), '西瓜大朗', fill=(0, 0, 128), font=img_font, )
    # my_io = BytesIO()
    # image_tmp.save(my_io, 'png')
    # return HttpResponse(my_io.getvalue())

    # 方式6 ,随机生成 5 大小写字母和数字,图片背景色和字的颜色每次不一样
    image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))
    # 把空图片放在了画板上
    draw = ImageDraw.Draw(image_tmp)
    # 加入字体
    img_font = ImageFont.truetype('./static/font/xgdl.ttf', 23)
    draw.text((0, 0), '西瓜大朗', fill=(0, 0, 128), font=img_font, )
    my_io = BytesIO()
    image_tmp.save(my_io, 'png')
    return HttpResponse(my_io.getvalue())




import random


def get_random_code():
    code = ''
    for i in range(5):
        # 随机生成一个大写字母
        upper_char = chr(random.randint(65, 90))
        low_char = chr(random.randint(97, 122))
        num_char = str(random.randint(0, 9))
        res = random.choice([upper_char, low_char, num_char])
        code += res
    return code


if __name__ == '__main__':
    print(get_random_code())

  

 

标签:username,登录,form,验证,bbs,校验,length,data,id
From: https://www.cnblogs.com/wzh366/p/17892657.html

相关文章

  • 运行时锁定正确性验证器 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/locking/lockdep-design.html锁类该验证器操作的基本对象是“锁”的“类”。“锁”的“类”是一组逻辑上相同的锁,即使这些锁可能有多个(可能有成千上万个)实例化。例如,inode结构中的锁是一个类,而每个inode都有自己的该锁类的实例化。验......
  • 宝塔面板申请ssl证书验证失败,域名解析错误或验证URL无法被访
    一、问题描述使用宝塔面板建立站点,申请let‘sEncrypt免费ssl证书时提示验证失败,域名解析错误或验证URL无法被访!网上找了各种方案检查防火墙配置,安全组配置,域名解析,nginx代理等等乱七八糟的配置检查来检查去发现都没问题,后来我注意到,这个错误提示是去访问本站点内的一个文......
  • SpringBoot项目之Kaptcha实现登录验证码
    一、pom.xml加载该依赖<dependency><groupId>com.github.axet</groupId><artifactId>kaptcha</artifactId><version>0.0.9</version></dependency>二、RestFul风格,在这里写一个调用验证码的接口:@GetMapping(value="/captcha.......
  • 使用selenium的edge浏览器登录某为
    互联网上基本都是某哥的用法,其实edge和某哥的用法是一样的就有一下参数不一样。一、运行环境Python:3.7Selenium:4.11.2Edge:版本120.0.2210.61(正式版本)(64位)编辑二、执行代码fromtimeimportsleepfromseleniumimportwebdriver#在这里导入浏览器设置相关的类fromse......
  • 『江鸟中原』鸿蒙——设计聊天软件界面并实现登录跳转
    环境搭建软件要求 DevEcoStudio版本:DevEcoStudio4.0Beta1BuildVersion:4.0.0.201,builtonJune10,2023。 HarmonyOSSDK版本:APIversion9。硬件要求设备类型:华为手机或运行在DevEcoStudio上的华为手机设备模拟器。HarmonyOS系统:3.1.0DeveloperRelease。简要介......
  • FastAPI-请求参数与验证
    最近想搞一下接口,希望能简单上手,前后端分离,大致看了一遍SpringBoot,Gin,NodeJs,Flask,Django,FastAPI等,感觉还是用Python语言来写比较简单呀,关键点在于它语法清晰,能让我直接思考业务逻辑,而不是各种语法折腾.FASTAPI简介Documentation:https://fastap......
  • JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证
    JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证背景部分客户的SQLServer数据库出现了大量死锁的情况.虽然部分客户并没有反馈死锁影响了产品的正常使用但是在大量业务时还是会出现卡顿等的现象基于此,经过微软case的研究,发现是JDBC4.0之后默认为ture的......
  • 基于FPGA的图像缩小算法实现,包括tb测试文件和MATLAB辅助验证
    1.算法运行效果图预览   将FPGA的处理结果导出到matlab中显示图像效果:   2.算法运行软件版本vivado2019.2 matlab2022a 3.算法理论概述      图像放小算法主要通过抽取算法实现,常见的抽取算法最大值抽取,和均值抽取。其示意图如下所示:    ......
  • 生物信息学与生物医学科学国际会议 (Inthernational Conference on Bioinformatics an
      。 01会议介绍生物信息学与生物医学科学国际会议(InthernationalConferenceonBioinformaticsandBiomedicalScience,ICBBS)每年举办一届,此前已在厦门(线上)、北京、深圳、曼谷、吉隆坡、哥本哈根、巴厘岛、新加坡成功举办,2021年第10届会议将在福建厦门线上举......
  • httpclient跳过SSL证书验证的写法
    最近在请求https接口的时候,发生了异常:sun.security.validator.ValidatorException:PKIXpathbuildingfailed:sun.security.provider.certpath.SuncertPathBuilderException:unabletofindvalidcertificationpathtorequestedtarget无法找到到请求目标的有效证书路......