zoukankan      html  css  js  c++  java
  • BBS项目(2)

    我们实现登录功能的随机验证码的产生

    views.py

    def get_random_color():
        return (
            # 创建三个0-255的随机数
            random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
        )
    
    
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
    
    
    def get_valid_code(request):
        img = Image.new('RGB', (320, 35), color=get_random_color())  # 构建一个画布
        img_draw = ImageDraw.Draw(img)  # 将画布img应用到画板
        font = ImageFont.truetype('static/font/ss.TTF', size=25)  # 创建字体对象
    
        random_code = ''  # 将随机产生的数字保存为字符串
        for i in range(5):  # 每一次调用循环5次
            char_num = random.randint(0, 9)  # 从0到9之间产生一个数字
            char_lower = chr(random.randint(97, 120))  # 产生小写字母 ascii码从97-120
            char_upper = chr(random.randint(65, 90))  # 产生大写字符 ascii码从65-90
            char_str = str(random.choice([char_num, char_lower, char_upper]))  # 从产生的三个对象(数字,大写,小写字母)中挑选一个
    
            # 将产生的随机对象通过img_draw.test放到img_draw中,第一个参数是范围
            # ,第二个参数是对象,第三个参数是颜色,font是字体
            img_draw.text((i * 30 + 20, 0), char_str, get_random_color(),font)
    
            random_code += char_str # 将产生的随机对象保存到random_code 中
    
    
        width = 320
        height = 35
        for i in range(20):
            x1 = random.randint(0, width)
            x2 = random.randint(0, width)
            y1 = random.randint(0, height)
            y2 = random.randint(0, height)
            # 将产生的线写到img_draw中,第一个参数是在画布img中的坐标,第二个参数是线条填充的颜色
            img_draw.line((x1, y1, x2, y2), fill=get_random_color()),
    
        for i in range(100):
            # 在画布img范围内随机产生点,第一个参数是坐标,第二个参数是点填充的颜色
            img_draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
            x = random.randint(0, width)
            y = random.randint(0, height)
            # 通过img_draw.arc添加线条,第一个参数是线条的其实坐标,第二个参数是开始和结束,第三个参数是填充的颜色
    
            img_draw.arc((x, y, x - 2, y + 3), 0, 9, fill=get_random_color())
    
        print(random_code)
        request.session['valid_code'] = random_code # 将收集到的随机对象保存在session中
        f = BytesIO() # 在内存中创建一个空文件
        img.save(f, 'png') # 将完成的画布img保存在文件f中,文件格式为png
        data = f.getvalue() # 拿到文件f的内容,并将其赋值给data
        return HttpResponse(data) # 将返回给前端页面

    前端的验证码代码

    <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>
                        <img width="300" height="35" src="/get_valid_code/" alt="">
                    </div>
                </div>

    点击验证码改变

    在前端页面

    <script>
        $('#img_code').click(function () {
            //在路径后面加一个问号
            $('#img_code')[0].src+='?'
        })
        
    </script>

     这样就能点击之后变换

    实现登录

    前端页面的方法

       $('#btn').click(function () {
            $.ajax({
                url: '/login/',
                type: 'post',
                data: {
                    'name': $('#name').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').html(data.msg)
    
                    }
    
    
                }
    
            })
        })

    后台登录代码

    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        # 判断前台是不是ajax请求
        # elif request.is_ajax():
        #     name=request.POST.get('name')
        #     pwd=request.POST.get('pwd')
        #     valid_code=request.POST.get('valid_code')
        #     if valid_code.upper==request.session.get('valid_code').upper():
        #         user=auth.authenticate(request,username=name,password=pwd)
        #         if user:
        #             pass
        #         else:
        #             # 用户名密码错误
        elif request.is_ajax():
            response={'user':None,'msg':None}
            name=request.POST.get('name')
            pwd=request.POST.get('pwd')
            valid_code=request.POST.get('valid_code')
            #判断传过来的验证码是否正确
            # 从session中取出来
            if valid_code.upper()==request.session['valid_code'].upper():
                #该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。
                user=auth.authenticate(request,username=name,password=pwd)
                if user:
                    # ajax请求,不能返回render页面,或者redirect,之前给你返回字符串
                    auth.login(request,user)
                    response['user']=name
                    response['msg']=pwd
    
                else:
                    # 用户名或密码错误
                    response['msg']='用户名或密码错误'
            else:
                response['msg']='验证码错误'
    
        return JsonResponse(response)

    实现注册

    views.py 中的register

    def register(request):
        if request.method=='GET':
            my_form=myforms.RegForm()
            return render(request,'register.html',{'my_form':my_form})
        elif request.is_ajax():
            response={'status':100,'msg':None}
            print(request.POST)
            my_form = myforms.RegForm(request.POST)
            if my_form.is_valid():
                # 存数据,返回正确信息
                # 得用create_user,回忆一下为什么
                # 定义一个字典,把清理的数据赋给它
                dic=my_form.cleaned_data
                # 移除掉确认密码字段
                dic.pop('re_password')
                # 取出上传的文件对象
                my_file=request.FILES.get('my_file')
    
                # 如果上传的文件为空,这个字段不传,数据库里存默认值
                if my_file:
                    # 放到字典中
                    dic['avatar']=my_file
                # 存数据的时候,多肯定不行,少,可以能行(null=True),它是可以的
                user=models.UserInfo.objects.create_user(**dic)
                '''
                models.FileField 有了这个字段,存文件,以及往数据库放文件路径,统统不需要自己做了
                只需要把文件对象赋给它就可以了
                '''
                # user=models.UserInfo.objects.create_user(username=name,password=pwd,avatar=文件对象)
                # 看看存没存进去
                print(user.username)
            else:
                # 返回错误信息
                response['status']=101
                response['msg']=my_form.errors
            return JsonResponse(response)
    View Code

    register.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <script src="/static/jquery-3.3.1.js"></script>
        <title>注册</title>
        <style>
            {#        把文件空间隐藏#}
            #my_file{
                display: none;
            }
        </style>
    
    {#    <script>#}
    {#        //等文档加载完毕之后,再进行操作#}
    {#        window.onload = function () {#}
    {#            //$("#id_name").val('lqz')#}
    {#        }#}
    {##}
    {#    </script>#}
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h1>注册</h1>
                <form id="form">
                    {% csrf_token %}
    
                    {% for foo in my_form %}
                        <div class="form-group">
                            <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
                            {{ foo }}
                        </div>
                    {% endfor %}
                    {# 加一个上传文件的控件#}
                    <div class="form-group">
                        <label for="my_file">头像
                            <img src="/static/img/default.png" id="img_file" alt="" width="80" height="80"
                                 style="margin-left: 10px">
                        </label>
    
                        <input type="file" id="my_file">
                    </div>
    
    
                    <input type="button" value="注册" class="btn btn-primary " id="btn"><span class="error"></span>
                </form>
    
            </div>
    
        </div>
    
    </div>
    </body>
    <script>
        //这个控件值发生变化的事件
        $("#my_file").change(function () {
            //alert(111)
            //先取出文件(图片)
            var file_obj = $("#my_file")[0].files[0];
            //通过文件阅读器,把图片放到img标签上
            //生成一个文件阅读器对象
            var filereader = new FileReader()
            //把图片对象,读到filereader对象中
            filereader.readAsDataURL(file_obj)
            //filereader.result 这是filereader对象的值
            //把文件对象渲染到img标签上(这样不行.需要加载完成才能操作)
            {#$("#img_file").attr('src', filereader.result)#}
            {#alert(1)#}
            //等加载完成,在操作
            filereader.onload=function () {
                $("#img_file").attr('src', filereader.result)
            }
    
    
        })
    
        $("#btn").click(function () {
            //因为要上传文件,生成formdata对象
            var formdata=new FormData()
            /*第一种方式
            formdata.append('name',$("#id_name").val())
            formdata.append('pwd',$("#id_pwd").val())
            formdata.append('re_pwd',$("#id_re_pwd").val())
            formdata.append('email',$("#id_email").val())
            formdata.append('csrfmiddlewaretoken',$('[name="csrfmiddlewaretoken"]').val())
            //把文件放到formdata中
            formdata.append('my_file',$('#my_file')[0].files[0])
            */
            //$("#form").serializeArray()把form表单打包,转成对象(列表套字典)
            var arr=$("#form").serializeArray()
            //第二种方式
            //jquery 的循环,传参数:第一个参数是要循环的对象,第二个参数是一个匿名函数
            $.each(arr,function (key,obj) {
                //obj对应的是:{name: "name", value: "sfdae"}
                console.log(key)
                console.log(obj)
                formdata.append(obj.name,obj.value)
            })
           //把文件放到formdata中
            formdata.append('my_file',$('#my_file')[0].files[0])
            console.log(arr)
    
            $.ajax({
                url:'/register/',
                type:'post',
                //写什么来?
                processData:false,
                contentType:false,
                data:formdata,
                success:function (data) {
                    console.log(data)
    
                }
            })
    
        })
    
    
    </script>
    
    {#    <script>#}
    {#        //等文档加载完毕之后,再进行操作#}
    {#        $("#id_name").val('lqz')#}
    {#    </script>#}
    </html>
    View Code

    form验证的myforms.py

    from django import forms
    
    from django.forms import widgets
    from django.core.exceptions import ValidationError
    from blog import models
    
    
    class RegForm(forms.Form):
        username = forms.CharField(max_length=18, min_length=2, label='用户名',
                                   widget=widgets.TextInput(attrs={'class': 'form-control'})
                                   )
        password = forms.CharField(max_length=18, min_length=2, label='密码',
                                   widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        re_password = forms.CharField(max_length=18, min_length=2, label='确认密码',
                                      widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        email = forms.EmailField(label='邮箱',
                                 widget=widgets.TextInput(attrs={'class': 'form-control'}))
    
        # 局部校验钩子函数
        def clean_username(self):
            name = self.cleaned_data.get('username')
            # 去数据库校验
            ret = models.UserInfo.objects.filter(username=name).first()
            if ret:
                raise ValidationError('用户名已存在')
            return name
    
        # 全局校验钩子函数
        def clean(self):
            pwd = self.cleaned_data.get('password')
            re_pwd = self.cleaned_data.get('re_password')
            if pwd and re_pwd:
                if pwd == re_pwd:
                    return self.cleaned_data
                else:
                    raise ValidationError('两次密码不一致')
    View Code
  • 相关阅读:
    python爬虫入门 爬图片的,用百度搜图,直接下,类型受限不过可以直接下,简单不少,下图片可以用
    TIME_WAIT状态原理(转)
    Unix网络编程的实现具体流程
    logistic损失函数的解释
    最大似然估计的复习(转)
    洛谷 P1022 计算器的改良
    洛谷P1012 拼数
    洛谷 P1073 最优贸易
    洛谷 P1098 字符串的展开
    洛谷 P3802 小魔女帕琪
  • 原文地址:https://www.cnblogs.com/ouyang99-/p/10032897.html
Copyright © 2011-2022 走看看