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:\Django\BBS01\app01\static\avatar\code1.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/'
请相信自己
当我们迷茫,懒惰,退缩的时候 我们会格外的相信命运 相信一切都是命中注定
而当我们努力拼搏,积极向上时 我们会格外的相信自己
所以命运是什么呢? 它是如果你习惯它 那它就会一直左右你
如果你想挣脱它 那它就成为你的阻碍 可如果你打破了它 那它就是你人生的垫脚石!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!