Django forms组件
校验字段
模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post"> <p>用户名: <input type="text" name="name"></p> {# <p>密码: <input type="text" name="pwd"></p>#} <p>确认密码: <input type="text" name="re_pwd"></p> <p>邮箱: <input type="text" name="email"></p> <input type="submit" value="提交"> </form> </body> </html>
视图文件
from django import forms
from django.forms import widgets
class MyForm(forms.Form):
# 定义一个属性,可以用来校验字符串类型
# 限制最大长度是8,最小长度是3
name = forms.CharField(max_length=8, min_length=3, label='用户名',
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},)
pwd = forms.CharField(max_length=8, min_length=3, required=True, label='密码',
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},)
re_pwd = forms.CharField(max_length=8, min_length=3, required=True, label='确认密码',
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},)
# 校验是否是邮箱格式
email = forms.EmailField(label='邮箱', error_messages={'required': '这个必须填', 'invalid': '不符合邮箱格式'})
数据从前端传过来,校验 要校验的字典,可以多参数,但是不能少 def index_form(request): # 生成对象时(实例化),需要传入要校验的数据(字典) if request.method=='GET': return render(request,'indxe.html') elif request.method=='POST': print(request.POST) myform=MyForm(request.POST) # is_valid如果是true表示校验成功,反之,校验失败 if myform.is_valid(): # 校验通过的数据 print(myform.cleaned_data) return HttpResponse('校验成功') else: print(myform.cleaned_data) # 错误信息,它是一个字典 print(myform.errors) print(myform.errors.as_data()) print(type(myform.errors)) from django.forms.utils import ErrorDict return HttpResponse('校验失败')
渲染模板
视图文件
from django.forms import widgets from django.forms import widgets from django.core.exceptions import ValidationError name = forms.CharField(widget=widgets.TextInput(attrs={'class': 'form-control'})) pwd = forms.CharField(widget=widgets.PasswordInput(attrs={'class': 'form-control'})) widgets 就是用来渲染的 class MyForm(forms.Form): # 定义一个属性,可以用来校验字符串类型 # 限制最大长度是8,最小长度是3 name = forms.CharField(max_length=8, min_length=3, label='用户名', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'}, widget=widgets.TextInput(attrs={'class': 'form-control'})) pwd = forms.CharField(max_length=8, min_length=3, required=True, label='密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'}, widget=widgets.PasswordInput()) re_pwd = forms.CharField(max_length=8, min_length=3, required=True, label='确认密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'}, widget=widgets.PasswordInput()) # 校验是否是邮箱格式 email = forms.EmailField(label='邮箱', error_messages={'required': '这个必须填', 'invalid': '不符合邮箱格式'}) 渲染模板 def index_form(request): # 生成对象时(实例化),需要传入要校验的数据(字典) myform=MyForm() if request.method=='GET': return render(request,'indxe2.html',locals())
模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <hr> <h1>第一种方式</h1> <form action="" method="post" > <p>用户名: {{ myform.name }}</p> <p>密码: {{ myform.pwd }}</p> <p>邮箱: {{ myform.email }}</p> <input type="submit" value="提交"> </form> <hr> <h1>第二种方式(for循环form对象,建议用这种)</h1> <form action="" method="post" > {% for foo in myform %} <p>{{ foo.label }}:{{ foo }}</p> {% endfor %} <input type="submit" value="提交"> </form> <h1>第三种方式(不建议用)</h1> <form action="" method="post" > {# {{ myform.as_p }}#} {{ myform.as_ul }} <input type="submit" value="提交"> </form> </body> </html>
渲染错误信息
视图文件
# 第一步:先要继承Form from django import forms from django.forms import widgets from django.core.exceptions import ValidationError # 写一个类 class MyForm(forms.Form): # 定义一个属性,可以用来校验字符串类型 # 限制最大长度是8,最小长度是3 name = forms.CharField(max_length=8, min_length=3, label='用户名', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'}, widget=widgets.TextInput(attrs={'class': 'form-control'})) pwd = forms.CharField(max_length=8, min_length=3, required=True, label='密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'}, widget=widgets.PasswordInput()) re_pwd = forms.CharField(max_length=8, min_length=3, required=True, label='确认密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'}, widget=widgets.PasswordInput()) # 校验是否是邮箱格式 email = forms.EmailField(label='邮箱', error_messages={'required': '这个必须填', 'invalid': '不符合邮箱格式'}) # aa = forms.CharField(label='选择', error_messages={'required': '这个必须填', 'invalid': '不符合邮箱格式'},widget=widgets.CheckboxInput()) def clean_name(self): # self:当前form对象 name = self.cleaned_data.get('name') if name.startswith('sb'): # 失败,抛异常 raise ValidationError('不能以傻逼开头') # 正常,把name返回 return name def clean(self): pwd=self.cleaned_data.get('pwd') re_pwd=self.cleaned_data.get('re_pwd') if pwd==re_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致') # 渲染错误信息 from app01 import models def index_form(request): # 生成对象时(实例化),需要传入要校验的数据(字典) if request.method == 'GET': myform = MyForm() elif request.method == 'POST': myform = MyForm(request.POST) if myform.is_valid(): print(myform.cleaned_data) myform.cleaned_data.pop('re_pwd') models.User.objects.create(**myform.cleaned_data) return redirect('http://www.baidu.com') else: all_error = myform.errors.get('__all__') if all_error: all_error=all_error[0] return render(request, 'indxe3.html', locals())
模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <title>Title</title> </head> <body> <h1>第二种方式(for循环form对象,建议用这种)</h1> <form action="" method="post" novalidate> {% for foo in myform %} <p>{{ foo.label }}:{{ foo }} <span>{{ foo.errors.0 }}</span></p> {% endfor %} <input type="submit" value="提交"><span>{{ all_error }}</span> </form> </body> </html> errors存放着错误信息
局部钩子
def clean_name(self): # self:当前form对象 name = self.cleaned_data.get('name') if name.startswith('sb'): # 失败,抛异常 raise ValidationError('不能以傻逼开头') # 正常,把name返回 return name clean_name 是拿上面定义的name 返回的信息也是放到 errors字典内 键是name 对应的值内
全局钩子
def clean(self): pwd=self.cleaned_data.get('pwd') re_pwd=self.cleaned_data.get('re_pwd') if pwd==re_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致') 全局钩子 错误的信息存放在 errors 字典内的 __all__ 键对应的值内
from django.shortcuts import render,HttpResponse import json from django.http import JsonResponse # Create your views here. from django import forms from django.forms import widgets from django.core.exceptions import ValidationError from app01 import models class myForm(forms.Form): name = forms.CharField(max_length=12, min_length=3, label='用户名', error_messages={'max_length': '最长是12', 'min_length': '最短是3', 'required': '必填'}, widget=widgets.TextInput(attrs={'class': 'form-control','id':'usr'})) pwd = forms.CharField(max_length=16, min_length=3, label='密码', error_messages={'max_length': '最长16', 'min_length': '最短是3', 'required': '必填'}, widget=widgets.PasswordInput(attrs={'class': 'form-control','id':'pwd'})) re_pwd = forms.CharField(max_length=16, min_length=3, label='再次输入密码', error_messages={'max_length': '最长16', 'min_length': '最短是3', 'required': '必填'}, widget=widgets.PasswordInput(attrs={'class': 'form-control','id':'pwd2'})) email = forms.EmailField(label='邮箱', error_messages={'required': '必填', 'invalid': '不符合邮箱格式'}, widget=widgets.EmailInput(attrs={'class': 'form-control','id':'email'})) def clean_name(self): name=self.cleaned_data.get("name") # print(name) account=models.User.objects.filter(name=name).first() if account: raise ValidationError('该用户名已存在') return name def clean(self): pwd = self.cleaned_data.get('pwd') # print(pwd) re_pwd = self.cleaned_data.get('re_pwd') if pwd == re_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致') def index(request): if request.method == 'GET': myform = myForm() return render(request, 'index.html', locals()) elif request.method == 'POST': # print(request.POST) # print(request.body) ajax1=json.loads(request.body.decode('utf-8')) # print(ajax1) myform = myForm(ajax1) if myform.is_valid(): data = myform.cleaned_data data.pop('re_pwd') models.User.objects.create(**data) return HttpResponse('注册成功') else: return JsonResponse(myform.errors) def index_usr(request): print(request.body) ajax2 = json.loads(request.body.decode('utf-8')) print(ajax2) myform = myForm(ajax2) if myform.is_valid(): return HttpResponse(json.dumps('可以使用的用户名')) else: return JsonResponse(myform.errors)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> <title>Title</title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3" id="msg"> <form action="" method="post" novalidate> {% for foo in myform %} <p id="{{ foo.auto_id }}">{{ foo.label }}:{{ foo }}</p> {% endfor %} </form> <button type="submit" id="btn">注册</button> <span id="error"></span> </div> </div> </div> </body> <script src="/static/jquery-3.3.1.js"></script> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script> <script> $('#btn').click(function () { var pos_data = { 'name': $('#usr').val(), 'pwd': $('#pwd').val(), 're_pwd': $('#pwd2').val(), 'email': $('#email').val() }; var pos = JSON.stringify(pos_data); $.ajax({ url: '/index/', type: 'post', data: pos, contentType: 'application/json', dataType: 'json', success: function (data) { for (let i in data) { var error_msg2 = $('<span class="pull-right" style="color: red" id="msg_error" >' + data[i] + '</span>'); if (error_msg2) { $('#msg_error').remove() } $('#id_' + i + '').append(error_msg2); if (data['__all__']) { var error_msg = $('<span class="pull-right" style="color: red" id="er_pwd2">' + data['__all__'] + '</span>'); if ($('#er_pwd2')) { $('#msg_error').remove() $('#er_pwd2').remove() } $('#id_re_pwd').append(error_msg) } else { $('#er_pwd2').remove() } break; } alert(data) } }) }); $('#usr').on('blur', function () { var pos_data2 = { 'name': $('#usr').val(), }; var pos2 = JSON.stringify(pos_data2); $.ajax({ url: '/index_usr/', type: 'post', data: pos2, contentType: 'application/json', dataType: 'json', success: function (data) { console.log(data) li='name' if (li in data) { var error_msg2 = $('<span class="pull-right" style="color: red" id="msg_error" >' + data['name'] + '</span>'); if (error_msg2) { $('#msg_error').remove() } $('#id_name').append(error_msg2); }else { var error_msg2 = $('<span class="pull-right" style="color: red" id="msg_error" >可以使用的用户名 </span>'); if (error_msg2) { $('#msg_error').remove() } $('#id_name').append(error_msg2); } } }) }) </script> </html>
from django.db import models # Create your models here. class User(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) email=models.EmailField()