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
原文地址:https://www.cnblogs.com/ouyang99-/p/10032897.html