bbs论坛登录相关功能(2)

昨天把注册功能页面做出来,接下来就是登录页面

  登录功能:

    1,用户账号,密码后台效验,错误信息在登录按钮右边显示

    2、验证码,根据图片生成,点击图片刷新产生新的验证码

  修改密码

  注册

  先把前端页面login.html页面编辑出来

{#login.html#}

<!
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> <link rel="stylesheet" href="/static/bootstrap-3.3.7/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> {% csrf_token %} <div class="form-group"> <label for="id_username">用户名:</label> <input type="text" name="username" id="id_username" class="form-control"> </div> <div class="form-group"> <label for="id_password">密码:</label> <input type="password" name="password" id="id_password" class="form-control"> </div> <div class="form-group">
            {#验证码这里一个输入框,一个图片#}
<label for="id_code">验证码:</label> <div class="row"> <div class="col-md-6"> <input type="text" name="code" id="id_code" class="form-control"> </div> <div class="col-md-6"> <img src="/static/img/default.png" alt="" width="280" height="30"> </div> </div> </div> <buttom class="btn btn-success" id="id_button">登录</buttom> </div> </div> </div> </body> </html>

前端效果:

前端web展示图片:

    方式1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/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>
                {% csrf_token %}
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name="username" id="id_username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name="password" id="id_password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_code">验证码:</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" name="code" id="id_code" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <img src="/get_code/" alt="" width="280" height="30">  {#指定路径#}
                        </div>
                    </div>
                </div>
                <buttom class="btn btn-success" id="id_button">登录</buttom>
        </div>
    </div>

</div>
</body>
</html>
# 设置urls.py路径
url(r'^get_code/',views.get_code)
# 设置views.py视图中的get_code函数
def get_code(request):
    # 推导,打开本地文件图片以二进制数据发送
    # 以2进制方式打开本地图片2.jpg,设置别名f
    with open(r'F:\老男孩Python7期\项目\bbs\register\avatar\2.jpg','rb') as f:
    # 读取图片数据赋值给变量data
        data =f.read()
    # return数据返回到前端
    return HttpResponse(data)

    方式2(使用模板pillow)

安装模块:

    pip3 install pillow

设置视图:

    

from PIL import Image,ImageDraw,ImageFont
# image用生成图片,imagedraw在图片上写字,imageFont字体样式
def get_code(request):
    # 推导方式2,动态生成图片,发送二进制数据
    img_obj = Image.new('RGB',(280,30),'red')
    # 以文件方式保存下来
    with open('demo.png','wb') as f:
        img_obj.save(f)
    # 再以二进制模式打开文件发送
    with open('demo.png','rb') as f:
        data=f.read()
    return HttpResponse(data)

实现固定颜色显示,怎么才刷新页面产生新的颜色呢?

  方式3:

    实现图片刷新,和图片存放

{#前端 login.html#}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/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>
                {% csrf_token %}
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name="username" id="id_username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name="password" id="id_password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_code">验证码:</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" name="code" id="id_code" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <img src="/get_code/" alt="" width="280" height="30">
                        </div>
                    </div>
                </div>
                <buttom class="btn btn-success" id="id_button">登录</buttom>
        </div>
    </div>

</div>
</body>
</html>

 

from PIL import Image,ImageDraw,ImageFont
import random
# 能够保存数据,取的时候二进制返回
from io import BytesIO

def get_random():
    # 随机生成三位随机数
    return random.randint(0,255),random.randint(0,255),random.randint(0,255)
def get_code(request):
# 推导3,图片颜色动态变化,图片存放不再依赖文件的形式
    img_obj= Image.new('RGB',(289,30),get_random())
    # 生成一个io对象
    io_obj = BytesIO()  # 将这个对象看作文件句柄
    img_obj.save(io_obj,'png')    # 将图片数据存入内存管理器中,必须要指定图片格式
    return HttpResponse(io_obj.getvalue())  # 将保存在内存管理器中的数据以二进制读取出来

 实现效果:前端页面刷新,验证码图片颜色变化

接下来在图片上显示验证码(数字)

前端保持不变,后端设置视图:

  

from PIL import Image, ImageDraw, ImageFont

import random
# 能够保存数据,取的时候二进制返回
from io import BytesIO
# 随机生成rgb参数
def get_random():
    # 随机生成三位随机数
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
def get_code(request):
    # 最终版本,颜色变化,显示数字
    img_obj = Image.new('RGB', (280, 30), get_random())
    # 生成一个画笔对象
    img_draw = ImageDraw.Draw(img_obj)  # 画笔就可以应用在该图片上
    # 生成一个字体对象
    img_font = ImageFont.truetype('static/font/mo.ttf', 30)

    # 随机验证码:数字+小写字母+大写字母
    code = ''  # 定义一个变量存储最终验证码
    for i in range(5):
        random_int = str(random.randint(0, 9))
        random_lower = chr(random.randint(97, 122))
        random_upper = chr(random.randint(65, 90))
        temp_code = random.choice([random_int, random_upper, random_lower])
        # 将产生的字一个一个写到图片上,(60,0)代表坐标x轴,y轴;temp_upper代表文本;img_font代表设置好的字体
        img_draw.text((60+i*30, 0), temp_code, get_random(), img_font)
        # code记录,控制间距
        code += temp_code
    print(code)
    # 将code存放到session表中
    request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj, 'png')
    return HttpResponse(io_obj.getvalue())

实现页面刷新,验证码也跟着变化:

 点击验证码颜色范围内,刷新新的验证码:

  后端不需要设置新的代码,前端需要修改当前这个图片的路径:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/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>
                {% csrf_token %}
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name="username" id="id_username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name="password" id="id_password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_code">验证码:</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" name="code" id="id_code" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <img src="/get_code/" alt="" width="280" height="30" id="id_img">
                        </div>
                    </div>
                </div>
                <buttom class="btn btn-success" id="id_button">登录</buttom>
        </div>
    </div>

</div>
<script>
    $('#id_img').click(function () {
        //获取原来路径
        let oldPath = $(this).attr('src');
        //修改图片的src属性
        $(this).attr('src',oldPath +='?')
    })
</script>
</body>
</html>

前端数据以ajax方式传到后端,后端进行处理

//login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/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>
                {% csrf_token %}
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name="username" id="id_username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name="password" id="id_password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_code">验证码:</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" name="code" id="id_code" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <img src="/get_code/" alt="" width="280" height="30" id="id_img">
                        </div>
                    </div>
                </div>
                <buttom class="btn btn-success" id="id_button">登录</buttom>
                <span class="errors" style="color: red" id="id_error"></span>
        </div>
    </div>

</div>
<script>
    $('#id_img').click(function () {
        //获取原来路径
        let oldPath = $(this).attr('src');
        //修改图片的src属性
        $(this).attr('src',oldPath +='?')
    })
    //发送数据
    $('#id_button').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:{
                'username':$('#id_username').val(),
                'password':$('#id_password').val(),
                'code':$('#id_code').val(),
                'csrfmiddlewaretoken':'{{ csrf_token }}',
            },
            success:function (data) {
                if (data.code == 100){
                    location.href = data.url
                } else{
                    $('#id_error').html(data.msg)
                }
            }
        })
    })
</script>
</body>
</html>
from django.contrib import auth
# 登录模块
def login(request):
    back_dic = {'code':100,'msg':''}
    if request.method =='POST':
        username=request.POST.get('username')
        password=request.POST.get('password')
        code=request.POST.get('code')
        # 先效验验证码,忽略大小写
        if request.session.get('code').upper() == code.upper():
            user_obj = auth.authenticate(username=username,password=password)
            if user_obj:
                # 登陆成功,记录当前状态
                auth.login(request,user_obj)
                back_dic['msg']='登陆成功'
                back_dic['url']='/home/'
            else:
                back_dic['code']=102
                back_dic['msg']='用户或者密码错误'
        else:
            back_dic['code']=103
            back_dic['msg']='验证码不正确'
        return JsonResponse(back_dic)
    return render(request, 'login.html')

首页(home)

# views.py
def home(request):
    return render(request, 'home.html')
//home.html  用户登录成功、事变都默认跳转到home页面,用户登录时导航栏显示当前用户,用户密码修改和退出;用户未登录的时候显示的是登录和注册
<!
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主页</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">BBS</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">文章 <span class="sr-only">(current)</span></a></li> <li><a href="#">随笔</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if request.user.is_authenticated %}  //使用auth判断用户是否登录 <li><a href="#">{{ request.user.username }}</a></li>  //显示当前登录用户 <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多操作 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="/set_password/">修改密码</a></li> <li><a href="#">修改头像</a></li> <li role="separator" class="divider"></li> <li><a href="/logout/">注销</a></li> </ul> </li> {% else %} <li><a href="/register/">注册</a></li> <li><a href="/login/">登录</a></li> {% endif %} </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> </body> </html>

实现效果(登录状态):

未登录状态:

退出功能:

  

# views.py
#
auth.logout退出后会自动清楚session def logout(request): auth.logout(request) return redirect('/home/')  # 退出后自动跳转到home页面

修改密码:

// set_password.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>修改密码</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h1 class="text-center">修改密码页面</h1> <form action="" method="post"> {% csrf_token %} <div class="form-group"> <label for="id_username">用户名:</label>
            {#request.user.username获取用户username的值,disabled禁用当前所在的栏 #}
<input type="text" name="username" id="id_username" value="{{ request.user.username }}" class="form-control" disabled> </div> <div class="form-group"> <label for="id_old_password">旧密码:</label> <input type="password" name="old_password" id="id_old_password" class="form-control"> </div> <div class="form-group"> <label for="id_password">输入密码:</label> <input type="password" name="password" id="id_password" class="form-control"> </div> <div class="form-group"> <label for="id_new_password">再次输入密码:</label> <input type="password" name="new_password" id="id_new_password" class="form-control"> </div> <button class="btn btn-success" id="id_button">确定修改</button>
            {#errors.id_button从后端获取键是id_button的值打印出来,style=“color:red”打印出来的字符显示红色#}
<span style="color: red">{{ errors.id_button }}</span> </form> </div> </div> </div> </body> </html>
# 修改密码
def set_password(request):
    # errors={'old_password':'','password':'','new_password':''}
    errors={'id_button':''}  #定义变量errors的键值,默认为空
    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        password = request.POST.get('password')
        new_password = request.POST.get('new_password')
        # print(old_password,password,new_password)
        # 从数据库中判断密码是否正确,前端明文会自动加密和后端对象的字段做对比
        res= request.user.check_password(old_password)
        # 判断原密码是否正确
        if res:
            if password == new_password:
                request.user.set_password(new_password)
                request.user.save()
                return redirect('/login/')
            else:
                errors['id_button']='输入的密码不一致'
        else:
            errors['id_button']='原密码输入不正确'return render(request, 'set_password.html',locals())  # locals()把前面定义的errors变量传递到前端

 原密码不正确:

输入的密码和二次输入的密码不一致

猜你喜欢

转载自www.cnblogs.com/yangzhaon/p/11061946.html