• BBS(仿博客园系统)项目02(登录(动态生成验证码)、主页搭建)


    一、登录功能实现: 

    html页面:

    ①login.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>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
        <link rel="stylesheet" href="/static/reg.css">
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3
                        col-sm-6 col-sm-offset-3
                        col-xs-8 col-xs-offset-2">
                <h2 class="text-center">登录页面</h2>
                <hr>
                {% csrf_token %}
                <div class="form-group">
                    <label for="id_username">用户名</label>
                    <input type="text" id="id_username" name="username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_password">密码</label>
                    <input type="password" id="id_password" name="password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_code">验证码</label>
                        <div class="row">
                            <div class="col-md-6
                                        col-sm-4
                                        col-xs-4">
                                <input type="text" id="id_code" name="code" class="form-control">
                            </div>
                            <div class="col-md-6
                                        col-sm-8
                                        col-xs-8">
                                <div class="col-md-7 col-sm-7 col-xs-7">
    {#                                验证码图片有后端生成,通过路由获取,宽度自适应,高度固定#}
                                    <img src="/get_code/" width="100%" height="60" id="id_code_img">
                                </div>
                                <div class="col-md-5 col-sm-5 col-xs-5">
                                    <span>看不清?点击图片换一张</span>
                                </div>
    
                            </div>
                        </div>
                </div>
                <button class="btn btn-primary" id="id_submit">登录</button>
    {#            此处显示错误提示,has-error是为了设置样式而设的类#}
                <span class="has-error" id="id_error"></span>
            </div>
        </div>
    </div>
    <script>
        // 验证码图片被点击,就在该src后面自动拼接一个问号?,后端只要发现路由有变化就会重新生成验证码图片
        $('#id_code_img').on('click',function () {
            let old_path = $(this).attr('src');
            $(this).attr('src',old_path+'?')
        });
        // 使用ajax提交数据,动态刷新login页面局部信息
        $('#id_submit').on('click',function () {
            $.ajax({
                url: '',
                type: 'post',
                data: {
                    'username':$('#id_username').val(),
                    'password':$('#id_password').val(),
                    'code':$('#id_code').val(),
                    'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val(),
                    //也可以使用这个
                    {#'csrfmiddlewaretoken': '{{ csrf_token }}',#}  
                },
                success:function (data) {
                    // 登录成功
                    if (data.code==100){
                        location.href = data.url
                    }
                    // 登录失败,将error的span标签加上内容
                    else {$('#id_error').html(data.msg)}
                }
    
            })
        })
    </script>
    </body>
    </html>
    ②set_password.html页面
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>BBS</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
        <link rel="stylesheet" href="/static/reg.css">
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h2 class="text-center">修改密码</h2>
                <hr>
                <form action="" method="post">
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="id_username">用户名</label>
                        <input type="text" class="form-control" name="username" id="id_username" disabled value="{{ request.user.username }}">
                    </div>
                    <div class="form-group">
                        <label for="id_old_password">原密码</label>
                        <input type="password" class="form-control" name="old_password" id="id_old_password">
                        <span class="has-error" id="id_old_password_error">{{ old_password_error }}</span>
                    </div>
                    <div class="form-group">
                        <label for="id_password">密码</label>
                        <input type="password" class="form-control" name="password" id="id_password">
                    </div>
                    <div class="form-group">
                        <label for="id_confirm_password">确认密码</label>
                        <input type="password" class="form-control" name="confirm_password" id="id_confirm_password">
                        <span class="has-error" id="id_confirm_password_error">{{ confirm_password_error }}</span>
                    </div>
                    <div class="form-group">
                    <button class="btn btn-primary" id="id_submit">提交修改</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <script>
        $('input').on('focus',function () {
            $(this).next().html('')
        })
    </script>
    </body>
    </html>
    ③home.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>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    </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 %}
                    <li><a href="">欢迎您</a></li>
                    <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="/login/">登录</a></li>
                        <li><a href="/register/">注册</a></li>
                    {% endif %}
                </ul>
            </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
    </nav>
    <div class="container-fluid">
        <div class="row">
    
        </div>
    
    </div>
    </body>
    </html>
    主页面导航条搭建
    ④css样式文件
    #myform span {
        color: red;
    }
    
    .has-error {
        color: red;
    }

    views.py视图函数

    ①随机验证码生成:
    # 随机生成颜色代码
    def get_random():
        return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
    
    # 从PIL(需下载)导入Image用来生成图片,ImageDraw在图片上写字,ImageFont图片上的字体样式
    from PIL import Image,ImageDraw,ImageFont,ImageFilter
    from io import BytesIO  # 帮我们保存数据,同时取得时候以二进制形式返回给我
    
    # 随机生成验证码图片
    def get_code(request):
        # 推导步骤1,打开本地文件发送二进制数据给前端传code图片
        '''
        with open(r'D:DjangoBBS01app01staticavatarcode1.jpg', 'rb') as f:
            data = f.read()
        return HttpResponse(data)
        '''
        # 推导步骤2,生成动态图片发送二进制数据
        ''''
        # img_obj = Image.new('RGB', (180, 35), 'red')
        # img_obj = Image.new('RGB', (180, 60), (128, 128, 128))
        img_obj = Image.new('RGB', (180, 60), get_random())
        # 先保存成文件
        with open('demo.png', 'wb') as f1:
            img_obj.save(f1)
        with open('demo.png', 'rb') as f2:
            return HttpResponse(f2.read())
        '''
        # 推导步骤3,图片存放不再依赖于文件的形式
        '''
        img_obj = Image.new('RGB', (180, 60), get_random())
        ## 生成一个BytesIO对象
        io_obj = BytesIO()  # 可以当做一个文件句柄f使用
        img_obj.save(io_obj, 'png')  # 将生成的图片数据存入内存管理器中,注意后面要指定图片后缀名
        return HttpResponse(io_obj.getvalue())
        # 通过io_obj.getvalue()来取出,取出的是二进制形式数据
        '''
        # 最后在图片上‘画’上字母和数字
        img_obj = Image.new('RGB', (180, 60), get_random())
        # 生成一个画笔对象
        img_draw = ImageDraw.Draw(img_obj)
        # 生成一个字体对象
        img_font = ImageFont.truetype('app01/static/code2.ttf', 48)
        # 随机验证码:数字+字母
        # 先定义一个code变量来记录生成的码,用于后面的校验
        code = ''
        for i in range(4):
            number = str(random.randint(0, 9))
            upper = chr(random.randint(97, 122))
            lower = chr(random.randint(65, 90))
            temp_code = random.choice([number, upper, lower])
            # 将随机的码写到图片上:
            img_draw.text((20+i*38, 10), temp_code, get_random(), img_font)
            #                坐标位置  随机生成的码  随机生成的颜色 码的字体样式
            # 注意这里需要一个字一个字的往图片里写码,每次写坐标要向右移动,这样码才不会叠加在一起
            code += temp_code
        # 此时img_obj图片对象里面就包含了4个随机码
        print(code)
        # 将code字符串存入session中,用于后面登录的校验
        request.session['code'] = code
        # 生成一个io对象帮助我们动态存随机生成的图片
        io_obj = BytesIO()
        # 设置图片模糊(了解)
        # img_obj = img_obj.filter(ImageFilter.BLUR)
        img_obj.save(io_obj, 'png')  # 将图片对象保存到io对象中
        return HttpResponse(io_obj.getvalue())
    ②登录相关视图函数,包括登录、注销、设置密码、主页简单搭建
    # 登录
    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').lower() == code.lower():
                # 通过auth.authenticate()方法,对用户进行认证
                user_obj = auth.authenticate(username=username, password=password)
                if user_obj:
                    # 如果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'] = 101
                back_dic['msg'] = '验证码错误'
            return JsonResponse(back_dic)
        return render(request, 'login.html')
    
    # 注销
    def logout(request):
        auth.logout(request)
        return redirect('/home/')
    
    # 主页
    def home(request):
        return render(request, 'home.html')
    
    # 修改密码
    from django.contrib.auth.decorators import login_required
    @login_required
    def set_password(request):
        if request.method == 'POST':
            old_password = request.POST.get('old_password')
            password = request.POST.get('password')
            confirm_password = request.POST.get('confirm_password')
            if request.user.check_password(old_password):  # 如果密码检查通过
                if password == confirm_password:
                    request.user.set_password(password)
                    request.user.save()
                    return redirect('/login/')
                else:
                    return render(request, 'set_password.html', {'confirm_password_error': '密码输入不一致'})
            else:
                return render(request, 'set_password.html', {'old_password_error': '原密码错误'})
    
        return render(request, 'set_password.html')

     其它相关配置

    # 路由urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^register/', views.register),
        url(r'^login/', views.login),
        url(r'^get_code/', views.get_code),
        url(r'^home/', views.home),
        url(r'^logout/', views.logout),
        url(r'^set_password/', views.set_password),
    ]
    
    # 配置文件settings.py
    # 设置默认跳转登录路由
    LOGIN_URL = '/login/'

     

  • 相关阅读:
    visual studio web开发调试禁用firefox缓存
    JSON C# Class Generator 由json字符串生成C#实体类的工具
    利用HttpHandler和Jquery进行数据库增改删查操作
    机器学习算法相关的开源架构介绍
    jquery validation plugin 中取消对指定按钮的有效性验证!
    Win7下附加sql2005数据库失败 错误代码5120的解决方法
    短地址服务goo.gl, bit.ly,x.co之间性能比较
    win7+iis7.5+asp.net下 CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案
    如何解决 The name ControlID does not exist in the current context 错误!
    mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource 错误的解决办法
  • 原文地址:https://www.cnblogs.com/suguangti/p/11061896.html
Copyright © 2020-2023  润新知