Django基于Form之登录和注册

Posted AmilyAmily

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django基于Form之登录和注册相关的知识,希望对你有一定的参考价值。

 

1、创建Forms文件,内容略多,大家将就着看,不懂请留言

 1 #!/usr/bin/env python
  2 # -*- coding: utf8 -*-
  3 #__Author: "Skiler Hao"
  4 #date: 2017/3/30 15:40
  5 from django.core.exceptions import ValidationError
  6 from django import forms
  7 from django.forms import fields
  8 from django.forms import widgets
  9 from django.core.validators import RegexValidator
 10 from respository import models
 11 
 12 
 13 class RegisterForm(forms.Form):
 14     username = fields.CharField(
 15         required=True,
 16         widget=widgets.TextInput(attrs={‘class‘: "form-control",‘placeholder‘: ‘用户名为8-12个字符‘}),
 17         min_length=6,
 18         max_length=12,
 19         strip=True,
 20         error_messages={‘required‘: ‘标题不能为空‘,
 21                         ‘min_length‘: ‘用户名最少为6个字符‘,
 22                         ‘max_length‘: ‘用户名最不超过为20个字符‘},
 23     )
 24     email = fields.EmailField(
 25         required=True,
 26         widget=widgets.TextInput(attrs={‘class‘: "form-control",‘placeholder‘: ‘请输入邮箱‘}),
 27         strip=True,
 28         error_messages={‘required‘: ‘邮箱不能为空‘,
 29                         ‘invalid‘:‘请输入正确的邮箱格式‘},
 30     )
 31     pwd = fields.CharField(
 32         widget=widgets.PasswordInput(attrs={‘class‘: "form-control",‘placeholder‘: ‘请输入密码,必须包含数字,字母,特殊字符‘},render_value=True),
 33         required=True,
 34         min_length=6,
 35         max_length=12,
 36         strip=True,
 37         validators=[
 38             # 下面的正则内容一目了然,我就不注释了
 39             RegexValidator(r‘((?=.*\d))^.{6,12}$‘, ‘必须包含数字‘),
 40             RegexValidator(r‘((?=.*[a-zA-Z]))^.{6,12}$‘, ‘必须包含字母‘),
 41             RegexValidator(r‘((?=.*[^a-zA-Z0-9]))^.{6,12}$‘, ‘必须包含特殊字符‘),
 42             RegexValidator(r‘^.(\S){6,10}$‘, ‘密码不能包含空白字符‘),
 43         ], #用于对密码的正则验证
 44         error_messages={‘required‘: ‘密码不能为空!‘,
 45                         ‘min_length‘: ‘密码最少为6个字符‘,
 46                         ‘max_length‘: ‘密码最多不超过为12个字符!‘,},
 47     )
 48     pwd_again = fields.CharField(
 49         #render_value会对于PasswordInput,错误是否清空密码输入框内容,默认为清除,我改为不清楚
 50         widget=widgets.PasswordInput(attrs={‘class‘: "form-control",‘placeholder‘: ‘请再次输入密码!‘},render_value=True),
 51         required=True,
 52         strip=True,
 53         error_messages={‘required‘: ‘请再次输入密码!‘,}
 54 
 55     )
 56 
 57     def clean_username(self):
 58         # 对username的扩展验证,查找用户是否已经存在
 59         username = self.cleaned_data.get(‘username‘)
 60         users = models.User.objects.filter(username=username).count()
 61         if users:
 62             raise ValidationError(‘用户已经存在!‘)
 63         return username
 64 
 65     def clean_email(self):
 66         # 对email的扩展验证,查找用户是否已经存在
 67         email = self.cleaned_data.get(‘email‘)
 68         email_count = models.User.objects.filter(email=email).count() #从数据库中查找是否用户已经存在
 69         if email_count:
 70             raise ValidationError(‘该邮箱已经注册!‘)
 71         return email
 72 
 73     def _clean_new_password2(self): #查看两次密码是否一致
 74         password1 = self.cleaned_data.get(‘pwd‘)
 75         password2 = self.cleaned_data.get(‘pwd_again‘)
 76         if password1 and password2:
 77             if password1 != password2:
 78                 # self.error_dict[‘pwd_again‘] = ‘两次密码不匹配‘
 79                 raise ValidationError(‘两次密码不匹配!‘)
 80 
 81     def clean(self):
 82         #是基于form对象的验证,字段全部验证通过会调用clean函数进行验证
 83         self._clean_new_password2() #简单的调用而已
 84 
 85 
 86 class loginForm(forms.Form):
 87     username = fields.CharField(
 88         required=True,
 89         widget=widgets.TextInput(attrs={‘class‘: "form-control",‘placeholder‘: ‘请输入用户名‘}),
 90         min_length=6,
 91         max_length=12,
 92         strip=True,
 93         error_messages={‘required‘: ‘用户名不能为空‘,}
 94     )
 95 
 96     pwd = fields.CharField(
 97         widget=widgets.PasswordInput(attrs={‘class‘: "form-control",‘placeholder‘: ‘请输入密码‘}),
 98         required=True,
 99         min_length=6,
100         max_length=12,
101         strip=True,
102         error_messages={‘required‘: ‘密码不能为空!‘,}
103     )
104 
105     def clean(self):
106         username = self.cleaned_data.get(‘username‘)
107         pwd = self.cleaned_data.get(‘pwd‘)
108         user = models.User.objects.filter(username=username).first()
109         if username and pwd:
110             if not user :
111 
112                 # self.error_dict[‘pwd_again‘] = ‘两次密码不匹配‘
113                 raise ValidationError(‘用户名不存在!‘)
114             elif pwd != user.password:
115                 raise ValidationError(‘密码不正确!‘)

2、login.html和register.html页面


技术分享图片
 1 {% extends ‘base/base.html‘ %}
 2 {% block head-resource %}
 3     {% load my_tags %}
 4 
 5     <!-- Custom styles for this template -->
 6     <link href="/static/css/signin.css" rel="stylesheet">
 7 
 8 {% endblock %}
 9 
10 {% block body-content %}
11     <div class="container">
12         <form class="form-signin" method="post" action="/login/" novalidate>{% csrf_token %}
13             {#            <h2 class="form-signin-heading">Please sign in</h2>#}
14             <label for="username">用户名</label>
15             {{ form.username }} <span style="color: red">{{ form.username.errors }}</span>
16             <label for="username">密码</label>
17             {{ form.pwd }} <span style="color: red">{{ form.username.errors }}</span>
18             <span style="color: red">
19                 {% if form|all_errors %}
20                     {{ form|all_errors }}
21                 {% endif %}
22             </span>
23             <div class="form-group">
24                 <label for="password">验证码</label>
25 
26                 <div class="row">
27                     <div class="col-xs-7">
28                         <input type="text" class="form-control" name="check_code" id="check_code" placeholder="请输入验证码">
29                     </div>
30                     <div class="col-xs-5">
31                         <img id="check_code_img" src="/create_code_img/" onclick="refresh_check_code(this)">
32 {#                        src是url路径,可得到验证码图片,点击时调用refresh_check_code#}
33                     </div>
34                 </div>
35                 <span style="color: red">{{ errors.check_code }}</span>
36             </div>
37             <div class="checkbox">
38                 <label>
39                     <input type="checkbox" value="1" name="auto_login"> 一个月内自动登陆
40                 </label>
41 
42                 <div class="right">
43                     <a href="#">忘记密码?</a>
44                 </div>
45             </div>
46             <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
47             <span>还没有账号?<a href="/register/">立即注册</a></span>
48         </form>
49 
50 
51     </div> <!-- /container -->
52 {% endblock %}
53 {% block body-js %}
54     <script>
55         function refresh_check_code(ths) {
56                 ths.src += ‘?‘;
57 {#                src后面加问好会自动刷新验证码img的src#}
58         }
59     </script>
60 
61 {% endblock %}
技术分享图片

技术分享图片
 1 {% load my_tags %}
 2 <!DOCTYPE html>
 3 <html>
 4 <head lang="en">
 5     <meta charset="UTF-8">
 6     <title></title>
 7     <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/>
 8     <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/>
 9     <link rel="stylesheet" href="/static/css/edmure.css"/>
10     <link rel="stylesheet" href="/static/css/commons.css"/>
11     <link rel="stylesheet" href="/static/css/account.css"/>
12     <style>
13 
14     </style>
15 </head>
16 <body>
17 <div class="register">
18     <div style="font-size: 25px; font-weight: bold;text-align: center;">
19         用户注册
20     </div>
21     <form role="form" action="/register/" method="POST" novalidate="NOVALIDATE">{% csrf_token %}
22         <div class="form-group">
23             <label for="username">用户名</label>
24             {{ form.username }}  <span style="color: red">{{ form.username.errors }}</span>
25 
26         </div>
27         <div class="form-group">
28             <label for="email">邮箱</label>
29             {{ form.email }}<span style="color: red">{{ form.email.errors }}</span>
30         </div>
31         <div class="form-group">
32             <label for="password">密码</label>
33             {{ form.pwd }}<span style="color: red">{{ form.pwd.errors.0 }}</span>
34         </div>
35         <div class="form-group">
36             <label for="confirm_password">确认密码</label>
37             {{ form.pwd_again }}
38             <span style="color: red">
39                 {{ form.pwd_again.errors.0 }}
40                 {% if form|all_errors %}
41                     {{ form|all_errors }}
42                 {% endif %}</span>
43         </div>
44 
45 
46         <input type="submit" class="btn btn-default" value="注册"/>
47     <span>已有账号?<a href="/login/">直接登录</a></span>
48     </form>
49 </div>
50 </body>
51 </html>

页面还有一些不合理的地方,欢迎大家批评指正

3、views视图内容


技术分享图片
  1 import datetime
  2 from django.shortcuts import render,redirect,HttpResponse
  3 from io import BytesIO
  4 
  5 from respository import models
  6 from utils import pagination
  7 from backend.forms import forms
  8 from utils import check_code
  9 # Create your views here.
 10 
 11 
 12 def login(request):
 13     # print(request.POST)
 14     if request.method == ‘GET‘:
 15         obj = forms.loginForm()
 16         # print(‘GET‘)
 17         return render(request,‘login.html‘,{‘form‘:obj})
 18 
 19     elif request.method == ‘POST‘:
 20         # print(request.POST)
 21         obj = forms.loginForm(request.POST)
 22         errors = {}
 23         if obj.is_valid():
 24             post_check_code = request.POST.get(‘check_code‘)
 25             session_check_code = request.session[‘check_code‘]
 26             if post_check_code.lower() == session_check_code.lower() :
 27             # values = obj.clean()
 28                 data = obj.cleaned_data
 29                 # print(data)
 30                 # print(data)
 31                 # print(obj.errors)
 32             # print(‘POST‘) 33                 if request.POST.get(‘auto_login‘):
 34                     request.session.set_expiry(60 * 60 * 24 *30)
 35                 request.session[‘is_login‘] = ‘true‘
 36                 request.session[‘user‘] = data.get(‘username‘)
 37                 print(request.session[‘username‘])
 38                 return redirect(‘/‘)
 39             else:
 40                 # print(obj.errors)
 41                 errors[‘check_code‘] = ‘请输入正确的验证码!‘
 42                 return render(request, ‘login.html‘, {‘form‘: obj,‘errors‘:errors})
 43 
 44         return render(request,‘login.html‘,{‘form‘:obj})
 45 
 46 def logout(request):
 47     try:
 48         #删除is_login对应的value值
 49         del request.session[‘is_login‘]
 50         del request.session[‘user‘]
 51     except KeyError:
 52         pass
 53     #点击注销之后,直接重定向回登录页面
 54     return redirect(‘/login/‘)
 55 
 56 def register(request):
 57     # username = models.CharField(max_length=16, verbose_name=‘用户名‘)
 58     # password = models.CharField(max_length=16, verbose_name=‘密码‘)
 59     # nickname = models.CharField(max_length=16,verbose_name=‘昵称‘)
 60     # email = models.EmailField(max_length=16, verbose_name=‘邮箱‘)
 61     # img = models.ImageField(verbose_name=‘头像‘,upload_to=‘static/img/user/‘,default=‘static/img/user/1.jpg‘)
 62     # ctime = models.DateTimeField(auto_created=True,verbose_name=‘创建时间‘)
 63 
 64     if request.method == ‘GET‘:
 65         obj = forms.Register()
 66         # return render(request,‘register.html‘,{‘form‘:obj})
 67     elif request.method == ‘POST‘:
 68         # print(request.POST)
 69         obj = forms.Register(request.POST)
 70         post_check_code =  request.POST.get(‘check_code‘)
 71         session_check_code = request.session[‘check_code‘]
 72         print(post_check_code,session_check_code)
 73         if obj.is_valid():
 74             if post_check_code ==  session_check_code:
 75             # values = obj.clean()
 76                 data = obj.cleaned_data
 77                 print(data)
 78                 # models.User.objects.create(
 79                 username= data.get(‘username‘)
 80                 password= data.get(‘pwd‘)
 81                 email= data.get(‘email‘)
 82                 nickname = data.get(‘username‘)
 83                 # )
 84                 models.User.objects.create(username=username,nickname =nickname,password =password,email = email )
 85                 request.session[‘is_login‘] = ‘true‘
 86                 request.session[‘user‘] = data.get(‘username‘)
 87                 return redirect(‘/‘)
 88         else:
 89             errors = obj.errors
 90             print(‘hello‘)
 91 
 92     return render(request,‘register.html‘,{‘form‘:obj})
 93 
 94 def article(request,*args,**kwargs):
 95     print(kwargs)
 96     return redirect(‘/‘)
 97 
 98 # 将check_code包放在合适的位置,导入即可,我是放在utils下面
 99 from utils import check_code
100 
101 def create_code_img(request):
102     f = BytesIO() #直接在内存开辟一点空间存放临时生成的图片
103 
104     img, code = check_code.create_validate_code() #调用check_code生成照片和验证码
105     request.session[‘check_code‘] = code #将验证码存在服务器的session中,用于校验
106     img.save(f,‘PNG‘) #生成的图片放置于开辟的内存中
107     return HttpResponse(f.getvalue())  #将内存的数据读取出来,并以HttpResponse返回
技术分享图片

4、说明:

urls和数据的创建我就不粘贴了,希望大家看了有所得,一起进步




以上是关于Django基于Form之登录和注册的主要内容,如果未能解决你的问题,请参考以下文章

django项目一:基于django2.2可重用登录与注册模块-注册页面

基于django的视频点播网站开发-step3-注册登录功能

django项目一:基于django2.2可重用登录与注册模块-Django表单

django项目一:基于django2.2可重用登录与注册模块-Django表单

Django框架之Forms组件(基于注册功能)

django 的form登录 注册