Django中Form验证

 Django的Form主要具有一下几大功能:

  • 生成HTML标签
  • 验证用户数据(显示错误信息)
  • HTML Form提交保留上次提交数据
  • 初始化页面显示内容

一,Form验证

第一种操作:主要是这三个函数

is_valid()

cleaned_data

errors

1from xiaoqing import models 2 3def form(request): 4 5 if request.method == "GET": 6 return render(request,'form.html') 7 elif request.method == "POST": 8 obj = FM(request.POST) 9 r1 = obj.is_valid() #is_valid() 让这个函数去验证 返回False 或者 True 10 print(r1) 11 if r1: 12 print(r1) 13 print(obj.cleaned_data) #cleaned_data表示返回的正确的信息 14 # models.Host.objects.create(**obj.cleaned_data) 15 else: 16 print(obj.errors.as_json()) #errors表示错误信息 17 18 return render(request,'form.html',{'obj':obj,}) 19 return redirect('/xiaoqing/host')

1<form action="/xiaoqing/form/" method="post"> 2 {% csrf_token %} 3{# {% for row in error_dict.keys %}#} 4 <p><input type="text" placeholder="请输入用户名" name="user"/><span style="color: red">{{ obj.errors.user.0 }}</span></p> 5 <p><input type="password" placeholder="请输入密码" name="pwd"/><span style="color: red">{{ obj.errors.pwd.0 }}</span></p> 6 <p><input type="text" placeholder="请输入邮箱" name="email"/><span style="color: red">{{ obj.errors.email.0 }}</span></p> 7 <input type="submit" value="提交"/> 8{# {% endfor %}#} 9 </form>

form.html

第二种操作:如果验证错误,用户信息不会消失

1def form(request): 2 3 if request.method == "GET": 4 obj = FM() #第一次用GET请求时,需要返回客户端一个对象 5 6 return render(request,'form.html',{'obj':obj}) 7 8 elif request.method == "POST": 9 obj = FM(request.POST) 10 r1 = obj.is_valid() #is_valid() 让这个函数去验证 返回False 或者 True 11 print(r1) 12 if r1: 13 print(r1) 14 print(obj.cleaned_data) #cleaned_data表示返回的正确的信息 15 # models.Host.objects.create(**obj.cleaned_data) 16 else: 17 print(obj.errors.as_json()) #errors表示错误信息 18 19 return render(request,'form.html',{'obj':obj,}) 20 return redirect('/xiaoqing/host')

views.py

1<form action="/xiaoqing/form/" method="post"> 2 {% csrf_token %} 3{# {% for row in error_dict.keys %}#} 4 <p>{{ obj.user }}<span style="color: red">{{ obj.errors.user.0 }}</span></p> 5 <p>{{ obj.pwd }}<span style="color: red">{{ obj.errors.pwd.0 }}</span></p> 6 <p>{{ obj.email }}<span style="color: red">{{ obj.errors.email.0 }}</span></p> 7 <input type="submit" value="提交"/> 8{# {% endfor %}#} 9 </form>

form.html

二,Form 自定义样式

1from django import forms 2from django.forms import widgets # 需要import 插件widgets 3from django.forms import fields #用fields 做字段验证 4 5 6class FM(forms.Form): 7 #字段本身只做验证 它不生成input标签 8 user = fields.CharField(error_messages={'required':'用户名不能为空'}, 9 widget=widgets.Textarea(attrs={'class':'c1'})) #用attrs 自定义样式 10 pwd = fields.CharField(max_length=12, 11 min_length=6, 12 error_messages={'required':'密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}, 13 widget=widgets.PasswordInput) 14 email = fields.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .c1 { 8 background-color: indianred; 9 10 } 11 12 </style> 13 14</head> 15<body> 16 17<div> 18 19{# <form action="/xiaoqing/form/" method="post">#} 20{# {% csrf_token %}#} 21{# {% for row in error_dict.keys %}#} 22{# <p><input type="text" placeholder="请输入用户名" name="user"/><span style="color: red">{{ obj.errors.user.0 }}</span></p>#} 23{# <p><input type="password" placeholder="请输入密码" name="pwd"/><span style="color: red">{{ obj.errors.pwd.0 }}</span></p>#} 24{# <p><input type="text" placeholder="请输入邮箱" name="email"/><span style="color: red">{{ obj.errors.email.0 }}</span></p>#} 25{# <input type="submit" value="提交"/>#} 26{# {% endfor %}#} 27{# </form>#} 28{##} 29 30 31 <form action="/xiaoqing/form/" method="post"> 32 {% csrf_token %} 33{# {% for row in error_dict.keys %}#} 34 <p>{{ obj.user }}<span style="color: red">{{ obj.errors.user.0 }}</span></p> 35 <p>{{ obj.pwd }}<span style="color: red">{{ obj.errors.pwd.0 }}</span></p> 36 <p>{{ obj.email }}<span style="color: red">{{ obj.errors.email.0 }}</span></p> 37 <input type="submit" value="提交"/> 38{# {% endfor %}#} 39 </form> 40 41 42</div> 43 44</body> 45</html>

form.html

创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML; 

1、Django内置字段如下:

1Field 2 required=True, 是否允许为空 3 widget=None, HTML插件 4 label=None, 用于生成Label标签或显示内容 5 initial=None, 初始值 6 help_text='', 帮助信息(在标签旁边显示) 7 error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} 8 show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) 9 validators=[], 自定义验证规则 10 localize=False, 是否支持本地化 11 disabled=False, 是否可以编辑 12 label_suffix=None Label内容后缀 13 14 15CharField(Field) 16 max_length=None, 最大长度 17 min_length=None, 最小长度 18 strip=True 是否移除用户输入空白 19 20IntegerField(Field) 21 max_value=None, 最大值 22 min_value=None, 最小值 23 24FloatField(IntegerField) 25 ... 26 27DecimalField(IntegerField) 28 max_value=None, 最大值 29 min_value=None, 最小值 30 max_digits=None, 总长度 31 decimal_places=None, 小数位长度 32 33BaseTemporalField(Field) 34 input_formats=None 时间格式化 35 36DateField(BaseTemporalField) 格式:2015-09-01 37TimeField(BaseTemporalField) 格式:11:12 38DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 39 40DurationField(Field) 时间间隔:%d %H:%M:%S.%f 41 ... 42 43RegexField(CharField) 44 regex, 自定制正则表达式 45 max_length=None, 最大长度 46 min_length=None, 最小长度 47 error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'} 48 49EmailField(CharField) 50 ... 51 52FileField(Field) 53 allow_empty_file=False 是否允许空文件 54 55ImageField(FileField) 56 ... 57 注:需要PIL模块,pip3 install Pillow 58 以上两个字典使用时,需要注意两点: 59 - form表单中 enctype="multipart/form-data" 60 - view函数中 obj = MyForm(request.POST, request.FILES) 61 62URLField(Field) 63 ... 64 65 66BooleanField(Field) 67 ... 68 69NullBooleanField(BooleanField) 70 ... 71 72ChoiceField(Field) 73 ... 74 choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),) 75 required=True, 是否必填 76 widget=None, 插件,默认select插件 77 label=None, Label内容 78 initial=None, 初始值 79 help_text='', 帮助提示 80 81 82ModelChoiceField(ChoiceField) 83 ... django.forms.models.ModelChoiceField 84 queryset, # 查询数据库中的数据 85 empty_label="---------", # 默认空显示内容 86 to_field_name=None, # HTML中value的值对应的字段 87 limit_choices_to=None # ModelForm中对queryset二次筛选 88 89ModelMultipleChoiceField(ModelChoiceField) 90 ... django.forms.models.ModelMultipleChoiceField 91 92 93 94TypedChoiceField(ChoiceField) 95 coerce = lambda val: val 对选中的值进行一次转换 96 empty_value= '' 空值的默认值 97 98MultipleChoiceField(ChoiceField) 99 ... 100 101TypedMultipleChoiceField(MultipleChoiceField) 102 coerce = lambda val: val 对选中的每一个值进行一次转换 103 empty_value= '' 空值的默认值 104 105ComboField(Field) 106 fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 107 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) 108 109MultiValueField(Field) 110 PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 111 112SplitDateTimeField(MultiValueField) 113 input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] 114 input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] 115 116FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 117 path, 文件夹路径 118 match=None, 正则匹配 119 recursive=False, 递归下面的文件夹 120 allow_files=True, 允许文件 121 allow_folders=False, 允许文件夹 122 required=True, 123 widget=None, 124 label=None, 125 initial=None, 126 help_text='' 127 128GenericIPAddressField 129 protocol='both', both,ipv4,ipv6支持的IP格式 130 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1PS:protocol必须为both才能启用 131 132SlugField(CharField) 数字,字母,下划线,减号(连字符) 133 ... 134 135UUIDField(CharField) uuid类型

参考:http://www.cnblogs.com/wupeiqi/articles/6144178.html 

自定义验证规则

1方式一: 2 3from django.forms import Form 4from django.forms import widgets 5from django.forms import fields 6from django.core.validators import RegexValidator 7 8class MyForm(Form): 9 user = fields.CharField( 10 validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')], 11 ) 12 13方式二: 14 15 16import re 17from django.forms import Form 18from django.forms import widgets 19from django.forms import fields 20from django.core.exceptions import ValidationError 21 22 23# 自定义验证规则 24def mobile_validate(value): 25 mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') 26 if not mobile_re.match(value): 27 raise ValidationError('手机号码格式错误') 28 29 30class PublishForm(Form): 31 32 33 title = fields.CharField(max_length=20, 34 min_length=5, 35 error_messages={'required': '标题不能为空', 36 'min_length': '标题最少为5个字符', 37 'max_length': '标题最多为20个字符'}, 38 widget=widgets.TextInput(attrs={'class': "form-control", 39 'placeholder': '标题5-20个字符'})) 40 41 42 # 使用自定义验证规则 43 phone = fields.CharField(validators=[mobile_validate, ], 44 error_messages={'required': '手机不能为空'}, 45 widget=widgets.TextInput(attrs={'class': "form-control", 46 'placeholder': u'手机号码'})) 47 48 email = fields.EmailField(required=False, 49 error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'}, 50 widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'})) 51 52方法三:自定义方法 53 54from django import forms 55 from django.forms import fields 56 from django.forms import widgets 57 from django.core.exceptions import ValidationError 58 from django.core.validators import RegexValidator 59 60 class FInfo(forms.Form): 61 username = fields.CharField(max_length=5, 62 validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.', 'invalid')], ) 63 email = fields.EmailField() 64 65 def clean_username(self): 66 """ 67 Form中字段中定义的格式匹配完之后,执行此方法进行验证 68 :return: 69 """ 70 value = self.cleaned_data['username'] 71 if "666" in value: 72 raise ValidationError('666已经被玩烂了...', 'invalid') 73 return value 74 75方式四:同时生成多个标签进行验证 76 77 78from django.forms import Form 79from django.forms import widgets 80from django.forms import fields 81 82from django.core.validators import RegexValidator 83 84 85############## 自定义字段 ############## 86class PhoneField(fields.MultiValueField): 87 def __init__(self, *args, **kwargs): 88 # Define one message for all fields. 89 error_messages = { 90 'incomplete': 'Enter a country calling code and a phone number.', 91 } 92 # Or define a different message for each field. 93 f = ( 94 fields.CharField( 95 error_messages={'incomplete': 'Enter a country calling code.'}, 96 validators=[ 97 RegexValidator(r'^[0-9]+$', 'Enter a valid country calling code.'), 98 ], 99 ), 100 fields.CharField( 101 error_messages={'incomplete': 'Enter a phone number.'}, 102 validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid phone number.')], 103 ), 104 fields.CharField( 105 validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.')], 106 required=False, 107 ), 108 ) 109 super(PhoneField, self).__init__(error_messages=error_messages, fields=f, require_all_fields=False, *args, 110 **kwargs) 111 112 def compress(self, data_list): 113 """ 114 当用户验证都通过后,该值返回给用户 115 :param data_list: 116 :return: 117 """ 118 return data_list 119 120############## 自定义插件 ############## 121class SplitPhoneWidget(widgets.MultiWidget): 122 def __init__(self): 123 ws = ( 124 widgets.TextInput(), 125 widgets.TextInput(), 126 widgets.TextInput(), 127 ) 128 super(SplitPhoneWidget, self).__init__(ws) 129 130 def decompress(self, value): 131 """ 132 处理初始值,当初始值initial不是列表时,调用该方法 133 :param value: 134 :return: 135 """ 136 if value: 137 return value.split(',') 138 return [None, None, None]

1# 单radio,值为字符串 2# user = fields.CharField( 3# initial=2, 4# widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) 5# ) 6 7# 单radio,值为字符串 8# user = fields.ChoiceField( 9# choices=((1, '上海'), (2, '北京'),), 10# initial=2, 11# widget=widgets.RadioSelect 12# ) 13 14# 单select,值为字符串 15# user = fields.CharField( 16# initial=2, 17# widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) 18# ) 19 20# 单select,值为字符串 21# user = fields.ChoiceField( 22# choices=((1, '上海'), (2, '北京'),), 23# initial=2, 24# widget=widgets.Select 25# ) 26 27# 多选select,值为列表 28# user = fields.MultipleChoiceField( 29# choices=((1,'上海'),(2,'北京'),), 30# initial=[1,], 31# widget=widgets.SelectMultiple 32# ) 33 34 35# 单checkbox 36# user = fields.CharField( 37# widget=widgets.CheckboxInput() 38# ) 39 40 41# 多选checkbox,值为列表 42# user = fields.MultipleChoiceField( 43# initial=[2, ], 44# choices=((1, '上海'), (2, '北京'),), 45# widget=widgets.CheckboxSelectMultiple 46# ) 47在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。 48 49方式一: 50 51from django.forms import Form 52from django.forms import widgets 53from django.forms import fields 54from django.core.validators import RegexValidator 55 56class MyForm(Form): 57 58 user = fields.ChoiceField( 59 # choices=((1, '上海'), (2, '北京'),), 60 initial=2, 61 widget=widgets.Select 62 ) 63 64 def __init__(self, *args, **kwargs): 65 super(MyForm,self).__init__(*args, **kwargs) 66 # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),) 67 # 或 68 self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption') 69方式二: 70 71使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现 72 73from django import forms 74from django.forms import fields 75from django.forms import widgets 76from django.forms import models as form_model 77from django.core.exceptions import ValidationError 78from django.core.validators import RegexValidator 79 80class FInfo(forms.Form): 81 authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) 82 # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

常用选择插件

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang