通过自己写的博客后台代码、思路,来与武sir的代码进行一个差异化的比较,记录之间的差距,改善以后写代码的思路
我的代码:
from django import forms from django.forms import fields from django.forms import widgets from repository import models from django.core.exceptions import ValidationError class LoginForm(forms.Form): username = fields.CharField( max_length=12, widget=widgets.Input(attrs={‘class‘:‘form-control‘,‘placeholder‘:"请输入用户名"}), error_messages={‘required‘: ‘用户名不能为空‘, ‘max_length‘: ‘密码长度不能大于12位‘} ) password = fields.CharField( max_length=12, min_length=6, widget=widgets.PasswordInput(attrs={‘class‘:‘form-control‘,‘placeholder‘:"请输入密码"}), error_messages={‘required‘: ‘密码不能为空‘, ‘min_length‘: ‘密码长度不能小于6位‘, ‘max_length‘: ‘密码长度不能大于12位‘} ) check_code = fields.CharField( error_messages={‘required‘: ‘验证码不能为空‘, } ) def clean(self): user_obj = models.UserInfo.objects.filter( username=self.cleaned_data.get(‘username‘),password=self.cleaned_data.get(‘password‘) ).first() if user_obj: return self.cleaned_data[‘username‘] else: raise ValidationError(message=‘用户名或密码错误‘) def clean_check_code(self): code = self.request.POST.get(‘check_code‘) if code.upper() == self.request.session[‘CheckCode‘].upper(): return self.cleaned_data[‘check_code‘] else: raise ValidationError(message=‘验证码错误‘) def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) if args: self.request = args[1]
from io import BytesIO from django.shortcuts import HttpResponse from django.shortcuts import render from django.shortcuts import redirect from utils.check_code import create_validate_code from web.views.form import LoginForm from web.views.form import RegisterForm from repository import models import json def check_code(request): """ 验证码 :param request: :return: """ # 1. 创建一张图片 pip3 install Pillow # 2. 在图片中写入随机字符串 # obj = object() # 3. 将图片写入到制定文件 # 4. 打开制定目录文件,读取内容 # 5. HttpResponse(data) stream = BytesIO() #在内存中生成一个文件对象 img, code = create_validate_code() #生成图片img和字符串code img.save(stream,‘PNG‘) #把验证图片存放到内存中以PNG名存放 request.session[‘CheckCode‘] = code #把生成的字符串code存放到session中 # print(‘验证码‘,code) return HttpResponse(stream.getvalue()) #stream.getvalue()返回图片的内容 def login(request): """ 登陆 """ if request.method == ‘GET‘: if request.session.get(‘is_login‘,None): return redirect(‘/index/‘) else: obj = LoginForm() return render(request, ‘login.html‘,{‘obj‘:obj}) elif request.method == ‘POST‘: data = {‘status‘: True, ‘error‘: None,} obj = LoginForm(request.POST,request) result = obj.is_valid() if result: print(‘验证通过‘) username = request.POST.get(‘username‘) user_dict = models.UserInfo.objects.filter(username=username).values(‘nid‘,‘username‘,‘nickname‘,‘email‘,‘blog__site‘, ‘blog__title‘,‘blog__theme‘)[0] for key in user_dict: request.session[key] = user_dict[key] request.session[‘is_login‘]=True if request.POST.get(‘rmb‘) == ‘0‘: request.session.set_expiry(60*60*24*30) else: print(obj.errors.as_json) data[‘status‘] = False data[‘error‘] = obj.errors return HttpResponse(json.dumps(data))
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> <link rel="stylesheet" href="/static/css/edmure.css"/> <link rel="stylesheet" href="/static/css/commons.css"/> <link rel="stylesheet" href="/static/css/account.css"/> <style> </style> </head> <body> <div class="login"> <div style="font-size: 25px; font-weight: bold;text-align: center;"> 用户登陆 </div> <form id=‘login_form‘ role="form" onsubmit = "return false" > <!--不进行跳转--> {% csrf_token %} <div class="form-group"> <label for="username">用户名</label> {# <input type="text" class="form-control" placeholder="请输入用户名">#} {{ obj.username }} </div> <div class="form-group"> <label for="password">密码</label> {# <input type="password" class="form-control" placeholder="请输入密码">#} {{ obj.password }} </div> <div class="form-group"> <label for="password">验证码</label> <div class="row"> <div class="col-xs-7"> <input type="text" class="form-control" placeholder="请输入验证码" name="check_code"> </div> <div class="col-xs-5"> <img id=‘changecheckcode‘ src="/check_code.html" onclick="changeCheckCode();"> <!--点击更换验证码--> </div> </div> </div> <div class="checkbox"> <label> <input type="checkbox" name="rmb" value="0"> 一个月内自动登陆 </label> <div class="right"> <a href="/register.html" style="margin-right: 10px">注册</a> <a href="#">忘记密码?</a> </div> </div> <button type="submit" id="loginsubmit" class="btn btn-default">登 陆</button> <div class="error_message"></div> </form> </div> <script src="/static/js/jquery-1.12.4.js"></script> <script src="/static/js/account.js"></script> <script src="/static/js/account_login.js"></script> </body> </html> function changeCheckCode(){ var img = $(‘#changecheckcode‘)[0]; img.src = img.src + ‘?‘; //刷新验证码 } function ShowError(error) { $(‘.error_message‘).text(error) } function EmptyError() { $(‘.error_message‘).text(‘‘) } /** * Created by L on 2017/2/17. */ $(‘#loginsubmit‘).click(function () { EmptyError() ; //清空错误 $.ajax({ url:‘/login.html‘, type:‘POST‘, data:$(‘#login_form‘).serialize(), dataType:‘JSON‘, success:function (data) { if(data[‘status‘]){ location.href = ‘/‘; //成功跳转 }else { var error_message = DateHandel(data); console.log(error_message) var error_message = ‘**‘ + error_message; ShowError(error_message) } },error:function () { } }) }); function DateHandel(data) { var error = data[‘error‘]; if(error[‘username‘]){ //用户名格式输入错误 var error_message = error[‘username‘][0] }else { if(error[‘password‘]){ //密码格式输入错误 var error_message = error[‘password‘][0] }else { if(error[‘check_code‘]){ //验证码为空 changeCheckCode(); var error_message = error[‘check_code‘][0] }else { if(error[‘__all__‘]){ var error_message = error[‘__all__‘][0] } } } } return error_message }
武sir的代码:
from django.core.exceptions import ValidationError from django import forms as django_forms from django.forms import fields as django_fields from django.forms import widgets as django_widgets from repository import models from .base import BaseForm class LoginForm(BaseForm, django_forms.Form): username = django_fields.CharField( min_length=6, max_length=20, error_messages={‘required‘: ‘用户名不能为空.‘, ‘min_length‘: "用户名长度不能小于6个字符", ‘max_length‘: "用户名长度不能大于32个字符"} ) password = django_fields.RegexField( ‘^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\%\^\&\*\(\)])[0-9a-zA-Z!@#$\%\^\&\*\(\)]{8,32}$‘, min_length=12, max_length=32, error_messages={‘required‘: ‘密码不能为空.‘, ‘invalid‘: ‘密码必须包含数字,字母、特殊字符‘, ‘min_length‘: "密码长度不能小于8个字符", ‘max_length‘: "密码长度不能大于32个字符"} ) rmb = django_fields.IntegerField(required=False) check_code = django_fields.CharField( error_messages={‘required‘: ‘验证码不能为空.‘} ) def clean_check_code(self): if self.request.session.get(‘CheckCode‘).upper() != self.request.POST.get(‘check_code‘).upper(): raise ValidationError(message=‘验证码错误‘, code=‘invalid‘)
from io import BytesIO from django.shortcuts import HttpResponse from django.shortcuts import render from django.shortcuts import redirect from utils.check_code import create_validate_code from repository import models from ..form.accout import LoginForm def check_code(request): """ 验证码 :param request: :return: """ stream = BytesIO() img, code = create_validate_code() img.save(stream, ‘PNG‘) request.session[‘CheckCode‘] = code return HttpResponse(stream.getvalue()) def login(request): """ 登陆 :param request: :return: """ if request.method == ‘GET‘: return render(request, ‘login.html‘) elif request.method == ‘POST‘: result = {‘status‘: False, ‘message‘: None, ‘data‘: None} form = LoginForm(request=request, data=request.POST) if form.is_valid(): username = form.cleaned_data.get(‘username‘) password = form.cleaned_data.get(‘password‘) user_info = models.UserInfo.objects. filter(username=username, password=password). values(‘nid‘, ‘nickname‘, ‘username‘, ‘email‘, ‘avatar‘, ‘blog__nid‘, ‘blog__site‘).first() if not user_info: # result[‘message‘] = {‘__all__‘: ‘用户名或密码错误‘} result[‘message‘] = ‘用户名或密码错误‘ else: result[‘status‘] = True request.session[‘user_info‘] = user_info if form.cleaned_data.get(‘rmb‘): request.session.set_expiry(60 * 60 * 24 * 7) else: print(form.errors) if ‘check_code‘ in form.errors: result[‘message‘] = ‘验证码错误或者过期‘ else: result[‘message‘] = ‘用户名或密码错误‘ return HttpResponse(json.dumps(result))
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> <link rel="stylesheet" href="/static/css/edmure.css"/> <link rel="stylesheet" href="/static/css/commons.css"/> <link rel="stylesheet" href="/static/css/account.css"/> </head> <body> <div class="login"> <div style="font-size: 25px; font-weight: bold;text-align: center;"> 用户登陆 </div> <form id="fm" method="POST" action="/login.html"> {% csrf_token %} <div class="form-group"> <label for="username">用户名</label> <input type="text" class="form-control" name="username" id="username" placeholder="请输入用户名"> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" class="form-control" name="password" id="password" placeholder="请输入密码"> </div> <div class="form-group"> <label for="password">验证码</label> <div class="row"> <div class="col-xs-7"> <input type="text" class="form-control" name="check_code" id="check_code" placeholder="请输入验证码"> </div> <div class="col-xs-5"> <img id="check_code_img" src="/check_code.html"> </div> </div> </div> <div class="checkbox"> <label> <input type="checkbox" value="1" name="rmb"> 一个月内自动登陆 </label> <div class="right"> <a href="#">忘记密码?</a> </div> </div> <div class="row"> <div class="col-xs-3"> <a id="submit" class="btn btn-default">登 陆</a> </div> <div class="col-xs-9" style="padding-left: 0;"> <div class="alert alert-danger hide"> <span style="padding: 0 5px 0 5px;display: inline-block;font-size: 14px"> <i class="fa fa-minus-circle" aria-hidden="true"></i> </span> <span id="error_msg" style="font-size: 12px;"></span> </div> </div> </div> </form> <script src="/static/js/jquery-1.12.4.js"></script> <script type="text/javascript"> $(function () { bindLogin(); }); function bindLogin() { $(‘#submit‘).click(function () { var $msg = $(‘#error_msg‘); $msg.parent().addClass(‘hide‘); $.ajax({ url: ‘/login.html‘, type: ‘POST‘, data: $(‘#fm‘).serialize(), dataType: ‘JSON‘, success: function (arg) { if(arg.status){ location.href = ‘/‘ }else{ $msg.parent().removeClass(‘hide‘); $msg.text(arg.message); var img = $(‘#check_code_img‘)[0]; img.src = img.src + ‘?‘; $(‘#password,#check_code‘).val(‘‘); } } }) }) } </script> </div> </body> </html>
区别:
①、前后端交互
前后端交互这块,自己没有活学活用,上课时老师讲课时讲到直接把obj.errors传到前端,然后就固执的这么用了,导致前端js要写很多的if进行判断(我的错误提示很完善,从不能为空,到用户错误,武sir这方面写的比较简单);武sir是直接向前端传输一个错误的字符串(result[‘message‘] = ‘用户名或密码错误‘),前端直接打印即可,js无需多的判断,如果想加多点的错误提示,可以在后台上多做写判断亦可
②、form验证
我from验证这一块,直接受到后台与前端传输数据为obj.errors影响,由于所有错误信息必须包含到obj.errors里面,导致用户密码验证必须写到form里面进行验证,获取用户名密码必须要把request传送到form,这个当时困住了好长时间,好算最后解决了,现在才发现self.request是直接可以调用的呀!!!;用户密码验证,武sir放到了处理函数里面,很机智
③、session信息
把要存的信息,key、value分别对应进行存储;武sir直接存了一个‘use_info’字段,包含了所有的信息
原文:http://www.cnblogs.com/lianzhilei/p/6415778.html