BBS项目搭建分步过程
2022-03-14 21:32
791 查看
BBS项目搭建分步过程
1. 注册页面补充完善
# 注册前端文件 register.html文件中补充: // 提交ajax $.ajax({ url: '', type: 'post', data: myFormData, contentType: false, processData: false, success: function (res) { console.log(res) if (res.status == 200) { layer.msg(res.msg, {icon:1}, function () { location.href = res.url; }) } else { layer.msg(res.msg,); } } }) }) </script> </body> </html> # views.py中补充: from django.http import JsonResponse from app01 import models # 1.注册功能 def register(request): # 后端一定要对参数进行验证 if request.method == 'POST': # 返回的是json格式的数据 back_dic = {'status': 200, 'msg': '注册成功', 'data': {}} # 1.1. 接收参数 username = request.POST.get('username') password = request.POST.get('password') re_password = request.POST.get('re_password') email = request.POST.get('email') img = request.POST.get('img') # 1.2. 验证参数, 先验证不正确的参数 if not username: ''' 响应状态码 业务状态码 财务相关的业务,用户相关的,订单相关的 1001 2001 30 ''' back_dic['status'] = 1001 back_dic['msg'] = '用户名必须填写' return JsonResponse(back_dic) if password != re_password: back_dic['status'] = 1002 back_dic['msg'] = '两次密码不一致' return JsonResponse(back_dic) # 验证用户名是否存在 res = models.UserInfo.objects.filter(username=username).first() if res: back_dic['status'] = 1003 back_dic['msg'] = '用户名已经存在' return JsonResponse(back_dic) # 1.3. 处理正确的业务逻辑 data_dic = {} if img != 'undefined': data_dic['avatar'] = img # 处理密码 import hashlib from django.conf import settings m = hashlib.md5() password = password + settings.SECRET_KEY m.update(password.encode('utf8')) password = m.hexdigest() data_dic['username'] = username data_dic['password'] = password data_dic['email'] = email # 1.4. 数据入库 models.UserInfo.objects.create(**data_dic) # 传入所有获取的数据 # 1.5. 返回数据 back_dic['url'] = '/login/' return JsonResponse(back_dic) return render(request, 'register.html')
2. 登录页面搭建
# views.py中写入登录以及验证码功能: # 2. 登录 def login(request): return render(request, 'login.html') # 3. 生成验证码 """ 图片相关的模块 pip3 install pillow """ from PIL import Image, ImageDraw, ImageFont """ Image:生成图片 ImageDraw:能够在图片上乱涂乱画 ImageFont:控制字体样式 """ from io import BytesIO, StringIO """ 内存管理器模块 BytesIO:临时帮你存储数据 返回的时候数据是二进制 StringIO:临时帮你存储数据 返回的时候数据是字符串 """ import random def get_random(): # (100, 100, 100) return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) def get_code(request): # 写图片验证码 img_obj = Image.new('RGB', (430, 35), get_random()) img_draw = ImageDraw.Draw(img_obj) # 产生一个画笔对象 img_font = ImageFont.truetype('static/font/font.ttf', 30) # 字体样式 大小 字体文件可自行百度下载 # 随机验证码 五位数的随机验证码 数字 小写字母 大写字母 code = '' for i in range(4): random_upper = chr(random.randint(65, 90)) random_lower = chr(random.randint(97, 122)) random_int = str(random.randint(0, 9)) # 从上面三个里面随机选择一个 tmp = random.choice([random_lower, random_upper, random_int]) # 将产生的随机字符串写入到图片上 """ 为什么一个个写而不是生成好了之后再写 因为一个个写能够控制每个字体的间隙 而生成好之后再写的话 间隙就没法控制了 """ img_draw.text((i * 60 + 60, -2), tmp, get_random(), img_font) # 拼接随机字符串 code += tmp print(code) # 随机验证码在登陆的视图函数里面需要用到 要比对 所以要找地方存起来并且其他视图函数也能拿到 request.session['code'] = code # request.session['code'] = code io_obj = BytesIO() img_obj.save(io_obj, 'png') return HttpResponse(io_obj.getvalue()) # 新建login.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container-fluid"> <div class="row"> <h1 class="text-center">登录页面</h1> <div class="col-md-8 col-md-offset-2"> <form action=""> <div class="form-group"> <label for="username">用户名</label> <input type="text" id="username" class="form-control"> </div> <div class="form-group"> <label for="username">密码</label> <input type="password" id="password" class="form-control"> </div> <div class="form-group"> <label for="myfile"> 验证码 </label> <div class="row"> <div class="col-md-6"> <input type="text" class="form-control" id="get_code"> </div> <div class="col-md-6"> <img src="/get_code/" id="re_code" alt="" style="width: 445px; height: 35px;"> </div> </div> </div> <input type="button" class="btn btn-success btn-block" value="登录"> </form> </div> </div> </div> </body> </html> # 路由不要忘了: # 登录页面 url(r'^login/', views.login), # 生成验证码 url(r'^get_code/', views.get_code),
3. 登录后端逻辑的实现
import hashlib from django.conf import settings # 封装密码处理功能 def get_pwd(password): m = hashlib.md5() password = password + settings.SECRET_KEY m.update(password.encode('utf-8')) return m.hexdigest() # 补充登录具体功能: # 2. 登录 def login(request): if request.method == 'POST': # 定义返回数据的格式 back_dic = {'status': 200, 'msg': '登录成功', } # 接收参数 username = request.POST.get('username') password = request.POST.get('password') code = request.POST.get('code') # 验证参数 if code.upper() != request.session.get('code').upper(): # .upper() 转大写 不区分大小写了 back_dic['status'] = 1004 back_dic['msg'] = '验证码不正确' return JsonResponse(back_dic) if not username: back_dic['status'] = 1005 back_dic['msg'] = '用户名必须填写' return JsonResponse(back_dic) # 登录逻辑 password = get_pwd(password) # 获取加密之后的密码 # res = models.UserInfo.objects.filter(username=username, password=password).first() '''防止撞库 同时查询用户名和密码 不要只匹配一项就返回结果给用户''' res = models.UserInfo.objects.filter(username=username, password=password).first() if not res: back_dic['status'] = 1006 back_dic['msg'] = '用户名或者密码不正确' return JsonResponse(back_dic) # 记录用户信息的 request.session['username'] = username request.session['id'] = res.id back_dic['url'] = '/home/' return JsonResponse(back_dic) return render(request, 'login.html') # 在login.html中 添加数据提交: """ 引入标签不要忘了: <script src="/static/layer-v3.5.1/layer/layer.js"></script> """ """body标签内添加script标签绑定事件:""" <script> // 更换验证码 $("#re_code").click(function () { {#var old_code = $('#re_code').attr('src');#} var old_code = $(this).attr('src'); {#$('#re_code').attr('src', old_code);#} $(this).attr('src', old_code); }) $('.btn').click(function () { var username = $('#username').val(); var password = $('#password').val(); var code = $('#get_code').val(); // 验证参数 if (!username) { layer.msg('用户名必须填写'); return } if (!password) { layer.msg('密码必须填写'); return; } if (!code) { layer.msg('验证码必须填写'); return; } var data = {'username': username, 'password': password, 'code': code} // 提交ajax 请求 $.ajax({ url: '', type: 'post', data: data, // 参数过多时 单独定义变量存储 success: function (res) { console.log(res); // 查看后端返回的数据, if (res.status == 200) { layer.msg(res.msg, {}, function () { location.href = res.url; }) } else { layer.msg(res.msg) } } }) }) </script>
4. 首页创建
# 路由: # 首页 url(r'^home/', views.home), # views.py补充首页功能: # 4. 首页 def home(request): return render(request, 'home.html', locals()) # 新建home.html文件 使用bootstrap的导航条样式: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-inverse"> <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="#">py20BBS</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="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> {% if request.session.username %} <li><a href="#">{{ request.session.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="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li> <li><a href="#">后台管理</a></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 class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="row"> <h1 class="text-center">修改密码</h1> <div class="col-md-8 col-md-offset-2"> <div class="form-group"> <label for="old_pwd"> 原密码: </label> <input type="text" id="old_pwd" class="form-control"> </div> <div class="form-group"> <label for="new_pwd"> 新密码: </label> <input type="text" id="new_pwd" class="form-control"> </div> <div class="form-group"> <label for="re_pwd">确认密码:</label> <input type="text" id="re_pwd" class="form-control"> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="button" class="btn btn-primary set_pwd">提交</button> </div> </div> </div> </div> </div> </div> </div><!-- /.container-fluid --> </nav> </body> </html>
5. 退出系统及修改密码功能的实现
# html文件内容在第4点 home.html文件中 # 添加路由: # 退出系统 url(r'^logout/', views.logout), # 修改密码 url(r'^set_pwd/', views.set_pwd), # views.py补充功能: # 5. 退出系统 def logout(request): request.session.flush() return redirect('/login/') # 6. 修改密码 def set_pwd(request): if request.method == 'POST': # 返回的是json格式的数据 back_dic = {'status': 200, 'msg': '修改成功', 'data': {}} # 1. 接收参数 old_pwd = request.POST.get('old_pwd') new_pwd = request.POST.get('new_pwd') re_pwd = request.POST.get('re_pwd') # 验证参数 if not old_pwd: back_dic['status'] = 1008 back_dic['msg'] = '原密码必须填写' return JsonResponse(back_dic) if re_pwd != new_pwd: back_dic['status'] = 1009 back_dic['msg'] = '两次密码不一致' return JsonResponse(back_dic) # 修改密码 password = get_pwd(new_pwd) # 获取加密之后的密码 models.UserInfo.objects.filter(pk=request.session.get('id')).update(password=password) return JsonResponse(back_dic) # html文件内容写在第4点home.html文件中: <script> $('.set_pwd').click(function () { var old_pwd = $('#old_pwd').val(); var new_pwd = $('#new_pwd').val(); var re_pwd = $('#re_pwd').val(); // 验证参数 if (!old_pwd) { layer.msg('原密码必须填写'); return } if (!new_pwd) { layer.msg('新密码必须填写'); return; } if (!re_pwd) { layer.msg('确认必须填写'); return; } var data = {'old_pwd': old_pwd, 'new_pwd': new_pwd, 're_pwd': re_pwd} // 提交ajax 请求 $.ajax({ url: '/set_pwd/', type: 'post', data: data, success: function (res) { console.log(res); // 查看后端返回的数据, if (res.status == 200) { layer.msg(res.msg, {}, function () { location.reload(); }) } else { layer.msg(res.msg) } } }) }) </script>
相关文章推荐
- eclipse 搭建activiti5.17项目生成流程过程
- Appfuse搭建过程(下源码不需要maven,lib直接就在项目里(否则痛苦死!))
- vue-cli3.0 脚手架搭建项目的过程详解
- win7搭建javaweb项目环境过程及遇到的问题
- mvnForum 一个开源的BBS搭建过程
- asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦
- Centos7 搭建Gitlab服务器并配置项目全过程
- Git服务器搭建全过程分步详解
- 【Spring Boot】使用Spring Boot来搭建Java web项目以及开发过程
- vue分层项目架构搭建过程与踩过的坑
- Koa项目搭建过程详细记录
- eslint 入门项目搭建过程
- BLUENESSG 早一日受苦、早一日解决、早一日浴火重生 Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题
- asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦
- Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出
- STS搭建SVN过程及同步项目(详细)
- Git服务器搭建全过程分步详解
- 搭建yii项目过程
- React Native项目环境搭建及运行过程中需要注意的细节
- spring-boot初学者:记一次搭建web项目404的错误排查过程