Django中 基于form的注册,基于ajax的登录
1 form.py中写register的的form组件
from django import forms class Register(forms.Form): # 注册的form username = forms.CharField( max_length=32,min_length=6, label='姓名', error_messages={ 'required':'用户名不能为空', 'invalid':'用户名输入格式有误', 'min_length':'用户名最小长度为6位', 'max_length':'用户名最小长度为6位', }, widget=forms.TextInput( attrs={ 'placeholder':'请输入用户名' } ))
password= forms.CharField( max_length=32, min_length=6, label='密码', error_messages={ 'required':'密码不能为空', 'invalid':'密码输入格式有误', 'min_length':'密码最短6位', 'max_lenth':'密码不能超过32位', }, widget=forms.PasswordInput( attrs={ 'placeholder':'请输入密码' } ), ) repassword = forms.CharField( max_length=32, min_length=6, label='确认密码', error_messages={ 'required': '确定密码不能为空', 'invalid': '确定密码格式错误', 'min_length': '确定密码最短6位', 'max_length': '确定密码最长32位', }, widget=forms.widgets.PasswordInput(attrs={"placeholder": "请输入确认密码"} ), ) telephone = forms.CharField( max_length=11, label="手机号码", required=False, error_messages={ }, validators=[RegexValidator(r'^[0-9]{11}$', '请输入11位手机号码'), RegexValidator(r'^(13|14|15|17)[0-9]{9}$', '手机号码必须以13/14/15/17开头')], widget=forms.widgets.TextInput(attrs={"placeholder": "请输入手机号码"}), ) email = forms.EmailField( label='邮箱', error_messages={ 'invalid': '邮箱格式错误', }, required=False, widget=forms.widgets.TextInput(attrs={"placeholder": "请输入邮箱"}), ) def clean_username(self): username = self.cleaned_data.get('username') ret = models.UserInfo.objects.filter(username=username).exists() print(ret) if ret: raise ValidationError('该用户名已存在') else: return username def clean_repassword(self): password = self.cleaned_data.get('password') repassword = self.cleaned_data.get('repassword') if password != repassword: raise ValidationError('密码不一致') else: return repassword def clean_phone(self): value = self.cleaned_data.get("phone") if models.UserInfo.objects.filter(phone=value).exists(): raise ValidationError("该手机号码已经注册") else: return value def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) for field in iter(self.fields): self.fields[field].widget.attrs.update({ 'class': 'form-control' })
2 写注册的视图函数
from web import form def register(request): """ 用户的注册 :param request: :return: """ if request.method =='GET': form_obj = form.Register() return render(request,'register.html',{'form_obj':form_obj}) else: form_obj = form.Register(request.POST) if form_obj.is_valid(): data = form_obj.cleaned_data data.pop('repassword') roles = data.pop('roles') # roles = request.POST.getlist() user_obj = models.UserInfo.objects.create_user(**data) user_obj.roles.set(roles) return redirect('login') else: return render(request,'register.html',{'form_obj':form_obj})
3 登录函数:
from PIL import Image,ImageDraw,ImageFont from io import BytesIO # 随机数 def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) # 验证码 def get_valid_img(request): # 图片对象 width = 190 height = 35 img_obj = Image.new('RGB', (width, height), get_random_color()) # 画笔对象 draw_obj = ImageDraw.Draw(img_obj) # 获取字体 font_path = os.path.join(settings.BASE_DIR, "web/static/font/font.ttf") # 字体对象 font_obj = ImageFont.truetype(font_path, 32) # 获取用户输入验证码的内容 sum_str = '' for i in range(4): a = random.choice( [str(random.randint(0, 9)), chr(random.randint(97, 122)), chr(random.randint(65, 90))]) sum_str += a # 通过画笔对象,添加文字 draw_obj.text((40, 0), sum_str, fill=get_random_color(), font=font_obj) # 添加噪线 for i in range(3): # 两点一线 x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, height) y2 = random.randint(0, height) draw_obj.line((x1, y1, x2, y2), fill=get_random_color()) # 添加噪点 for i in range(3): draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw_obj.arc((x, y, x + 8, y + 8), 0, random.randint(0, 360), fill=get_random_color()) # from io import BytesIO # 操作内存的手柄 f = BytesIO() img_obj.save(f, 'png') data = f.getvalue() # 将验证码存在各用户自己的session中 request.session["valid_str"] = sum_str print(sum_str) return HttpResponse(data) def login(request): """ 用户登录 相应的状态码: 成功:1000 验证码失败:1001 用户名密码失败:1002 :param request: :return: """ response_msg = {'code':None,'msg':None} if request.method == 'GET': return render(request,'login.html') else: username = request.POST.get('username') password = request.POST.get('password') #得到验证码 valid_core = request.POST.get('valid_core') if valid_core.upper() == request.session.get('valid_str').upper(): #验证是否登录成功 user_obj = auth.authenticate(username=username,password=password) if user_obj: #将用户的信息放入session中 #session注入 persission_input(request,user_obj) response_msg['code']=1000 response_msg['msg']='用户名密码正确' else: response_msg['code'] = 1002 response_msg['msg'] = '用户名或密码错误' else: response_msg['code']=1001 response_msg['msg']='验证码输入错误' return JsonResponse(response_msg) def logout(request): """退出登录,并清除session""" auth.logout(request) return redirect('login')
4 register的html register.html:
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> </head> <body> <h1>注册界面</h1> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="{% url 'register' %}" method="post" novalidate> {% csrf_token %} {% for foo in form_obj %} <div class="form-group"> <label for="{{ foo.id_for_label }}" class="control-label"> {{ foo.label }}</label> {{ foo }} <span class="text-danger"> {{ foo.errors.0 }}</span> </div> {% endfor %} <input type="submit" class="btn btn-primary pull-right" value="注册"> </form> </div> </div> </div> <script src="{% static 'bootstrap-3.3.7-dist/js/jquery-3.4.1.js' %}"></script> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </body> </html>
5 登录的html login.html
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> </head> <body> <h1>登录界面</h1> <div class="container-fluid"> <div class="row"> {% csrf_token %} <div class="col-md-4 col-md-offset-4"> <div class="form-group"> <label for="username" >用户名</label> <input type="text" name = "username" id="username" class="form-control"> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" name="password" id="password" class="form-control"> </div> <div class="form-group"> <label for="valid_core">验证码</label> <div class="row"> <div class="col-sm-6"> <input type="text" name="valid_core" id="valid_core" class="form-control"></div> {# 得到验证码#} <div class="col-sm-6"> <img src="{% url 'get_valid_img' %}" alt="" id="valid_core_img"> </div> </div> </div> <span class="error"></span> <button type="button" class="btn btn-primary pull-right login">登录</button> </div> </div> </div> <script src="{% static 'bootstrap-3.3.7-dist/js/jquery-3.4.1.js' %}"></script> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> <script> $('.login').on('click',function () { console.log(111) var username = $('[name=username]').val(); var password = $('[name=password]').val(); var valid_core = $('[name=valid_core]').val(); var csrf_token = $('[name=csrfmiddlewaretoken]').val() console.log(csrf_token) $.ajax({ url:"{% url 'login' %}", type:'post', data:{ username: username, password:password, valid_core:valid_core, csrfmiddlewaretoken:csrf_token }, success:function (res) { if (res.code === 1000){ var href = location.search.slice(6); if (href){ location.href = href }else { location.href ='{% url 'index' %}' } }else { $('.error').text(res.msg) } } }) }) $('#valid_core_img').click(function () { console.log($(this)) $(this)[0].src +='?'; }) </script> </body> </html>