django表单基础
django表单分类
- 基于django.forms.Form:所有表单类的父类
- 基于django.forms.ModelForm:可以和模型类绑定的Form
Form验证流程
- 定义规则(是一个类)
- 前端把数据提交过来
- 匹配规则
- 判断提交过来的数据是否符合定义的规则
- 如果匹配返回True,否则返回errors,可以把这个errors返回给前端,让前端显示到指定位置(比如用户名没填写,验证码没填写)
注意:
规则中的字段名必须得等于html中name的值
Form表单方法
form.is_valid():验证表单数据是否合法
form.errors:表单的错误以字典形式返回(如果有多个错误,可以循环这个字典,然后传给前端)
form.clean_data:获取表单数据
form.as_p:将表单渲染成P标签
普通form
实例1:实现用户登录验证,如果用户输入符合规则就跳转,否则报错
定义urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), ]
定义views.py
from django.shortcuts import render,HttpResponse import json from django import forms # Create your views here. #定义用户输入规则 class LoginForm(forms.Form): user = forms.CharField(required=True,error_messages={'required':'用户名不能为空'}) pwd = forms.CharField(required=True) def login(request): if request.method == 'POST': result = {'status': False,'message':None} obj = LoginForm(request.POST) #request.POST是获取用户前端输入内容,例如:<QueryDict: {'pwd': ['1111'], 'user': ['11111'], 'undefined': ['提交']}> ret =obj.is_valid() #判断用户输入是否符合上面LoginForm定义的规则,如果符合返回True,否则范围False(符合规则就是 比如:不能为空,最大输入字符为10个等等) if ret: print(obj.clean()) #obj.clean()方法是获取用户输入内容(例如:{'pwd': '1111', 'user': '11111'}) result['status'] = True #如果符合规则置为true else: print(obj.errors) #obj.errors是获取用户输入的错误信息,比如说规则里定义了不能为空,但是用户输入为空了,就会报错(例如:<li>pwd<ul class="errorlist"><li>This field is required.</li></ul>) error_str = obj.errors.as_json() #也可以将错误信息输出为json格式,例如:{"pwd": [{"code": "required", "message": "This field is required."}]} print('aaaaaaa',error_str) #这行没用,用来标记的 result['message'] = json.loads(error_str) #如果不符合规则就把错误信息写到字典里(例如:{'status': False,'message':{"pwd": [{"code": "required", "message": "This field is required."}]}}) print('bbbbbb',result) #这行没用,用来做标记的 return HttpResponse(json.dumps(result)) #最后把result字典传给前端ajax return render(request,'login.html')
定义login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> . error-message { color: red; } </style> </head> <body> <div> <input type="text" name="user"/> </div> <div> <input type="password" name="pwd"/> </div> <input type="button" value="提交" onclick="SubmitForm()"/> <script src="/static/jquery.min.js"></script> <script> function SubmitForm() { var input_dict = {}; $('input').each(function () { var v = $(this).val(); var n = $(this).attr('name'); input_dict[n] = v; }); $.ajax({ url: '/login/', type: 'POST', data: input_dict, dataType: 'json', success: function (callback) { #后端处理完数据返回数据后执行success这部分函数,callback是形参,意思是接收一个参数(接收的数据格式例如:{'status': False,'message':{'pwd': [{'message': 'This field is required.', 'code': 'required'}]}}) if(callback.status){ #如果status=true就跳转 location.href = '/index'; }else{ #如果status=FALSE $.each(callback.message,function (k,v) { #callback.message就是{'pwd': [{'message': 'This field is required.', 'code': 'required'}]},然后把key赋值给function的k,把vulue赋值给function的value,key就是pwd,value就是列表里的 var tag = document.createElement('span'); #创建一个span标签 tag.className = 'error-message'; #给span标签添加样式 tag.innerText = v[0].message; #给span标签赋值,v[0]就获取到字典的value就是{'message': 'This field is required.', 'code': 'required'}. 然后v[0].message在获取value,就是This field is required $('input[name="' + k + '"]').after(tag); #然后拼接,获取input标签name等于k(这个k就是function传进来的k,这里代表pwd),在后边添加span标签,加个error-message的样式,内容为This field is required }) } } }) } </script>
效果测试
实例2:错误信息自定义
定义urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), ]
定义views.py
from django.shortcuts import render,HttpResponse import json from django import forms # Create your views here. #定义用户输入规则 class LoginForm(forms.Form): user = forms.CharField(required=True,error_messages={'required':'用户名不能为空'}) pwd = forms.CharField(required=True,min_length=6,max_length=10, error_messages={'required':'密码不能为空', 'min_length':'最少输入6位', 'max_length':'最多输入10位'} ) def login(request): if request.method == 'POST': result = {'status': False,'message':None} obj = LoginForm(request.POST) #request.POST是获取用户前端输入内容,例如:<QueryDict: {'pwd': ['1111'], 'user': ['11111'], 'undefined': ['提交']}> ret =obj.is_valid() #判断用户输入是否符合上面LoginForm定义的规则,如果符合返回True,否则范围False(符合规则就是 比如:不能为空,最大输入字符为10个等等) if ret: print(obj.clean()) #obj.clean()方法是获取用户输入内容(例如:{'pwd': '1111', 'user': '11111'}) result['status'] = True #如果符合规则置为true else: print(obj.errors) #obj.errors是获取用户输入的错误信息,比如说规则里定义了不能为空,但是用户输入为空了,就会报错(例如:<li>pwd<ul class="errorlist"><li>This field is required.</li></ul>) error_str = obj.errors.as_json() #也可以将错误信息输出为json格式,例如:{"pwd": [{"code": "required", "message": "This field is required."}]} print('aaaaaaa',error_str) #这行没用,用来标记的 result['message'] = json.loads(error_str) #如果不符合规则就把错误信息写到字典里(例如:{'status': False,'message':{"pwd": [{"code": "required", "message": "This field is required."}]}}) print('bbbbbb',result) #这行没用,用来做标记的 return HttpResponse(json.dumps(result)) #最后把result字典传给前端ajax return render(request,'login.html')
定义login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> . error-message { color: red; } </style> </head> <body> <div> <input type="text" name="user"/> </div> <div> <input type="password" name="pwd"/> </div> <input type="button" value="提交" onclick="SubmitForm()"/> <script src="/static/jquery.min.js"></script> <script> function SubmitForm() { var input_dict = {}; $('input').each(function () { var v = $(this).val(); var n = $(this).attr('name'); input_dict[n] = v; }); $.ajax({ url: '/login/', type: 'POST', data: input_dict, dataType: 'json', success: function (callback) { #后端处理完数据返回数据后执行success这部分函数,callback是形参,意思是接收一个参数(接收的数据格式例如:{'status': False,'message':{'pwd': [{'message': 'This field is required.', 'code': 'required'}]}}) if(callback.status){ #如果status=true就跳转 location.href = '/index'; }else{ #如果status=FALSE $.each(callback.message,function (k,v) { #callback.message就是{'pwd': [{'message': 'This field is required.', 'code': 'required'}]},然后把key赋值给function的k,把vulue赋值给function的value,key就是pwd,value就是列表里的 var tag = document.createElement('span'); #创建一个span标签 tag.className = 'error-message'; #给span标签添加样式 tag.innerText = v[0].message; #给span标签赋值,v[0]就获取到字典的value就是{'message': 'This field is required.', 'code': 'required'}. 然后v[0].message在获取value,就是This field is required $('input[name="' + k + '"]').after(tag); #然后拼接,获取input标签name等于k(这个k就是function传进来的k,这里代表pwd),在后边添加span标签,加个error-message的样式,内容为This field is required }) } } }) } </script>
测试
ModelForm
有时候表单form字段和model字段是一一对应的,因此分别定义form类model类比较麻烦,modelform就是根据model的字段生成form字段
实例一:modelForm验证
定义models.py
class userAsk(models.Model): '''用户咨询,页面中间部分 我要学习 表单提交''' name = models.CharField(max_length=20,verbose_name='姓名') mobile = models.CharField(max_length=11,verbose_name='手机') course_name = models.CharField(max_length=50,verbose_name='课程名称') add_time = models.DateTimeField(default=datetime.now,verbose_name='添加时间') class Meta: verbose_name = '用户咨询' verbose_name_plural = '用户咨询'
定义forms.py
from django import forms from operation.models import userAsk import re class UserAskForm(forms.ModelForm): class Meta: model = userAsk fields = ['name','mobile','course_name'] def clean_mobile(self): #自定义mobile字段的验证,必须得这么写(定义name字段就是clean_name) #获取mobile字段内容 mobile = self.cleaned_data['mobile'] #定义验证规则 p = re.compile('^0d{2,3}d{7,8}$|^1[358]d{9}$|^147d{8}') #把获取到的mobile字段进行验证 #如果验证通过 if p.match(mobile): # 这里还能返回外键 return mobile #如果验证失败,这个错误信息可以通过.errors获取 else: raise forms.ValidationError('mobile error', code='mobile_inval')
定义views.py
from .forms import * import json class AddUserAsk(View): def post(self,request): ret = {'status':False,'msg':None} user_ask_form = UserAskForm(request.POST) if user_ask_form.is_valid(): user_ask_form.save(commit=True) ret['status'] = True return HttpResponse(json.dumps(ret),content_type="application/json") else: ret['status'] = False ret['msg'] = '请确认信息填写正确' return HttpResponse(json.dumps(ret),content_type="application/json")
定义html
<div class="right companyright"> <div class="head">我要学习</div> <form class="rightform" id="jsStayForm"> <div> <img src="{% static 'images/rightform1.png' %}"/> <input type="text" name="name" id="companyName" placeholder="名字" maxlength="25" /> </div> <div> <img src="{% static 'images/rightform2.png' %}"/> <input type="text" name="mobile" id="companyMobile" placeholder="联系电话"/> </div> <div> <img src="{% static 'images/rightform3.png' %}"/> <input type="text" name="course_name" id="companyAddress" placeholder="课程名" maxlength="50" /> </div> <p class="error company-tips" id="jsCompanyTips"></p> <input class="btn" type="button" value="立即咨询" onclick="SubmitForm()"/> {% csrf_token %} </form> </div> <script> function SubmitForm() { $.ajax({ type: 'POST', url: "{% url 'org:add_ask' %}", data:$('#jsStayForm').serialize(), success: function (callback) { if (callback['status']) { alert('提交成功') } else { $('#jsCompanyTips').html(callback['msg']) } } }) } </script>