1. urls.py
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^register/', views.register), ]
2.model.py
class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() pwd = models.CharField(max_length=12)
3.Vies.py
def register(request): # 只有当请求为 POST 时,才表示用户提交了注册信息 if request.method=='POST': # request.POST 是一个类字典数据结构,记录了用户提交的注册信息 # 这里提交的就是用户名(username)、密码(password)、邮箱(email) # 用这些数据实例化一个用户注册表单 obj = forms.RegisterForm(request.POST) if obj.is_valid(): # 验证数据的合法性 username = obj.cleaned_data.get('username') password = obj.cleaned_data.get('pwd') email = obj.cleaned_data.get('email') models.User.objects.create(username=username,pwd=password,email=email) # 注册成功,跳转XXX页 return HttpResponse('register success') else: print(obj.errors) else: # 请求不是 POST,表明用户正在访问注册页面,展示一个空的注册表单给用户 obj = forms.RegisterForm() # 渲染模板 # 如果用户正在访问注册页面,则渲染的是一个空的注册表单 # 如果用户通过表单提交注册信息,但是数据验证不合法,则渲染的是一个带有错误信息的表单 return render(request,'register.html',{'form':obj})
def register(request): if request.method=='POST': obj = forms.RegisterForm(request.POST) if obj.is_valid(): username = obj.cleaned_data.get('username') password = obj.cleaned_data.get('pwd') email = obj.cleaned_data.get('email') models.User.objects.create(username=username,pwd=password,email=email) return HttpResponse('register success') else: print(obj.errors) else: obj = forms.RegisterForm() return render(request,'register.html',{'form':
def login(request): if request.method=='POST': obj = forms.loginForm(request.POST) if obj.is_valid(): username = obj.cleaned_data['username'] password = obj.cleaned_data['pwd'] namefilter = models.User.objects.filter(username=username,pwd=password) if namefilter: return HttpResponse('OK') else: print(obj.errors.as_data()) else: obj = forms.loginForm() return render(request,'login.html',{'form':obj})
4.forms.py
from django import forms from django.forms import fields,widgets from app01 import models from django.core.validators import RegexValidator from django.core.exceptions import ValidationError class RegisterForm(forms.Form): username = fields.CharField( required=True, widget=widgets.TextInput(attrs={'placeholder': '用户名为8-12个字符'}), min_length=6, max_length=12, strip=True, error_messages={ 'required':'标题不能为空', 'min_length':'用户名最少为6个字符', 'max_length':'用户名最不超过为20个字符' } ) email = fields.EmailField( required=True, widget=widgets.TextInput(attrs={'placeholder': '请输入邮箱'}), # strip=True, error_messages={'required': '邮箱不能为空', 'invalid':'请输入正确的邮箱格式'} ) pwd = fields.CharField( required=True, widget=widgets.PasswordInput(attrs={'placeholder': '请输入密码,必须包含数字,字母,特殊字符'}), min_length=6, max_length=12, # strip=True, # validators=[ # RegexValidator(r'((?=.*d))^.{6,12}$', '必须包含数字'), # RegexValidator(r'((?=.*[a-zA-Z]))^.{6,12}$', '必须包含字母'), # RegexValidator(r'((?=.*[^a-zA-Z0-9]))^.{6,12}$', '必须包含特殊字符'), # RegexValidator(r'^.(S){6,10}$', '密码不能包含空白字符'), # ], error_messages={ 'required':'密码不能为空', 'min_length':'密码最少6个字符', 'max_length':'密码不超过12个字符' } ) pwd_again = fields.CharField( widget=widgets.PasswordInput(attrs={ 'placeholder': '请再次输入密码!'}), required=True, error_messages={'required': '请再次输入密码!!!!'} ) def clean_username(self): username = self.cleaned_data.get('username') users = models.User.objects.filter(username=username).count() if users: raise ValidationError('用户已经存在!') return username def clean_email(self): email = self.cleaned_data.get('email') email_count = models.User.objects.filter(email=email).count() if email_count: raise forms.ValidationError('邮箱已经存在!') return email def clean(self): # cleaned_data = super(RegisterForm,self).clean() password1 = self.cleaned_data.get('pwd') password2 = self.cleaned_data.get('pwd_again') if password1 and password2 and password1 != password2: # raise forms.ValidationError('两次输入密码不一致') self.add_error('pwd_again','两次输入密码不一致') return None else: return self.cleaned_data # def _clean_new_password2(self): # password1 = self.cleaned_data.get('pwd') # password2 = self.cleaned_data.get('pwd_again') # if password1 != password2: # raise ValidationError('两次输入密码不一致') # # def clean(self): # self._clean_new_password2()
class loginForm(forms.Form): username = fields.CharField( required=True, widget=widgets.TextInput(attrs={'placeholder': '请输入用户名'}), min_length=6, max_length=12, error_messages={'required':'用户名不能为空'} ) pwd = fields.CharField( widget=widgets.PasswordInput(attrs={'placeholder': '请输入密码'}), required=True, min_length=6, max_length=12, error_messages={'required':'密码不能为空'} ) def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('pwd') c = models.User.objects.filter(username=username,pwd=password) if c: return self.cleaned_data else: self.add_error('pwd','用户名或密码不一致') return None # def clean_username(self): # username = self.cleaned_data.get('username') # email_count = models.User.objects.filter(username=username).count() # if not email_count: # raise ValidationError('用户名不存在!') # return username # # def clean_pwd(self): # password = self.cleaned_data.get('pwd') # email_count = models.User.objects.filter(pwd=password).count() # if not email_count: # raise ValidationError('密码错误!')
5.HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/register/" method="post"> {% csrf_token %} <p> <label>用户名:</label> {{ form.username }}<span style="color: red">{{ form.errors.username }}</span> </p> <p> <label>密码:</label> {{ form.pwd }}<span style="color: red">{{ form.errors.pwd }}</span> </p> <p> <label>再次输入密码:</label> {{ form.pwd_again }}<span style="color: red">{{ form.errors.pwd_again }}</span> </p> <p> <label>邮箱:</label> {{ form.email }}<span style="color: red">{{ form.errors.email }}</span> </p> <input type="submit" value="提交"></input> </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="/login/"> {% csrf_token %} <label for="username">用户名</label>{{ form.username }} <label for="password">密码</label> {{ form.pwd }}<span style="color: red">{{ form.errors.pwd }}</span> <input type="submit" value="提交"></input> </form> </body> </html>
6.form验证某个字段 self.clean_字段名
def clean_username(self): username = self.cleaned_data.get('username') users = models.User.objects.filter(username=username).count() if users: raise ValidationError('用户已经存在!') return username # self.errors = {'code': ['用户已经存在!'], 'xx':[错误1,错误2]}
form验证多个字段 self.clean
def clean(self): #此时,已经拿到所有的input值,对两次输入密码进行验证 # cleaned_data = super(RegisterForm,self).clean() password1 = self.cleaned_data.get('pwd') password2 = self.cleaned_data.get('pwd_again') if password1 and password2 and password1 != password2: raise forms.ValidationError('两次输入密码不一致')# 默认放到self.errors['__all__']里面 else: return self.cleaned_data “”“ self.errors = {'__all__': ['两次输入密码不一致'], 'xx':[错误1,错误2]} NON_FIELD_ERRORS = '__all__' 前台获取需要用到 此时前端获取该错误; obj.non_field_errors ”“”
form验证多个字段 self.clean 指明错误信息的Key,方便前端使用
def clean(self): # cleaned_data = super(RegisterForm,self).clean() password1 = self.cleaned_data.get('pwd') password2 = self.cleaned_data.get('pwd_again') if password1 and password2 and password1 != password2: self.add_error('pwd_again','两次输入密码不一致') # 此时不用抛出异常了,因为抛出异常 # 抛出异常也是执行self.add_error return None else: return self.cleaned_data 此时在前端显示该错误: obj.errors.pwd_again
form 的错误信息self.errors
# form标签数据验证错误信息 self.errors = {'username':[错误1, 错误2], 'password': [错误1, 错误2]} def clean_xx(self) 如果遇到错,放到self.errors['xx']里面 def clean(self) 如果遇到错,放到self.errors['__all__']里面 但是如果要前端获取self.errors['__all__']错误,obj.errors.__all__是拿不到的 而是obj.non_field_errors, 不是self.errors.non_fields_errors