Python自动化运维系列之Django Form表单验证
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python自动化运维系列之Django Form表单验证相关的知识,希望对你有一定的参考价值。
Form表单验证
Django核心功能组件之一,虽然也可以在前端使用JS对表单验证, 但是Django中已经为我们准备好的Form功能还算是很强大的,有时候比较适合运维,为我们简化了很多前端开发工作。
Django最主要的几个功能有4个
· 生成HTML标签
· 验证数据(表单错误信息提示)
· HTML 表单保留上次提交数据
· 初始化页面表单内容
Django的Form内容还是挺多的,我们可以从一个简单的登陆验证例子来看看Form的基本功能使用
1)新建URL
urlpatterns = [ url(r‘^fm/$‘, views.fm), ]
2)views视图里创建FM类
from django import forms from django.forms import widgets from django.forms import fields // FM继承forms.Form class FM(forms.Form): // 用户名字段 user = fields.CharField( error_messages={‘required‘: ‘用户名不能为空.‘}, widget=widgets.TextInput(attrs={‘class‘: ‘c1‘}), label="用户名", ) // 密码字段 pwd = fields.CharField( max_length=12, min_length=6, error_messages={‘required‘: ‘密码不能为空.‘, ‘min_length‘: ‘密码长度不能小于6‘, "max_length": ‘密码长度不能大于12‘}, widget=widgets.PasswordInput(attrs={‘class‘: ‘c2‘}), label="密码" ) // 邮箱字段 email = fields.EmailField(error_messages={‘required‘: ‘邮箱不能为空.‘,‘invalid‘:"邮箱格式错误"},label="邮箱") // select字段 city1 = fields.ChoiceField( choices=[(0,‘上海‘),(1,‘广州‘),(2,‘北京‘)],label="城市")
3)views中创建fm函数
def fm(request): if request.method == ‘GET‘: // 实例化我们创建的FM类 obj = FM() return render(request, ‘fm.html‘, {‘obj‘: obj}) elif request.method == ‘POST‘: // 如果是POST请求 需要以request.POST为参数 obj = FM(request.POST) ret = obj.is_valid() if ret: print(ret) else: return render(request, ‘fm.html‘, {‘obj‘: obj}) return render(request, ‘fm.html‘)
4)编辑HTML页面模版
<body> <form action="/fm/" method="POST"> {% csrf_token %} // obj对象在前端可以直接用点取后面的字典值 <p>{{ obj.user.label }} {{ obj.user }} {{ obj.errors.user.0 }}</p> <p>{{ obj.pwd.label }} {{ obj.pwd }} {{ obj.errors.pwd.0 }}</p> <p>{{ obj.email.label }} {{ obj.email }}{{ obj.errors.email.0 }}</p> {{ obj.city1.label }} {{ obj.city1 }} <input type="submit" value="提交" /> </form> </body>
5)运行程序看前端显示页面
Django已经为我们创建好了HTML代码
6)当提交表单验证数据有效性
7)初始化HTML
def fm(request): if request.method == ‘GET‘: dic = { "user": ‘root‘, ‘pwd‘: ‘123456‘, ‘email‘: ‘[email protected]‘, ‘city1‘: 2, } // 使用inital初始化我们查询到的dic数据 obj = FM(initial=dic) return render(request, ‘fm.html‘, {‘obj‘: obj}) elif request.method == ‘POST‘: obj = FM(request.POST) ret = obj.is_valid() if ret: print(ret) else: return render(request, ‘fm.html‘, {‘obj‘: obj}) return render(request, ‘fm.html‘)
初始化完成
Form类
创建Form时,主要涉及到【字段】和【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;
1)Django内置字段
// Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text=‘‘, 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {‘required‘: ‘不能为空‘, ‘invalid‘: ‘格式错误‘} show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) validators=[], 自定义验证规则 localize=False, 是否支持本地化 disabled=False, 是否可以编辑 label_suffix=None Label内容后缀 // CharField(Field) max_length=None, 最大长度 min_length=None, 最小长度 strip=True 是否移除用户输入空白 // IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 // FloatField(IntegerField) ... // DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 总长度 decimal_places=None, 小数位长度 // BaseTemporalField(Field) input_formats=None 时间格式化 // DateField(BaseTemporalField) 格式:2015-09-01 // TimeField(BaseTemporalField) 格式:11:12 // DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 // DurationField(Field) 时间间隔:%d %H:%M:%S.%f ... // RegexField(CharField) regex, 自定制正则表达式 max_length=None, 最大长度 min_length=None, 最小长度 error_message=None, 忽略,错误信息使用 error_messages={‘invalid‘: ‘...‘} // EmailField(CharField) ... // FileField(Field) allow_empty_file=False 是否允许空文件 // ImageField(FileField) ... 注:需要PIL模块,pip3 install Pillow 以上两个字典使用时,需要注意两点: - form表单中 enctype="multipart/form-data" - view函数中 obj = MyForm(request.POST, request.FILES) // URLField(Field) ... // BooleanField(Field) ... // NullBooleanField(BooleanField) ... // ChoiceField(Field) ... choices=(), 选项,如:choices = ((0,‘上海‘),(1,‘北京‘),) required=True, 是否必填 widget=None, 插件,默认select插件 label=None, Label内容 initial=None, 初始值 help_text=‘‘, 帮助提示 // ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查询数据库中的数据 empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中value的值对应的字段 limit_choices_to=None # ModelForm中对queryset二次筛选 // ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField // TypedChoiceField(ChoiceField) coerce = lambda val: val 对选中的值进行一次转换 empty_value= ‘‘ 空值的默认值 // MultipleChoiceField(ChoiceField) ... // TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 对选中的每一个值进行一次转换 empty_value= ‘‘ 空值的默认值 // ComboField(Field) fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) // MultiValueField(Field) PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 // SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:[‘%Y--%m--%d‘, ‘%m%d/%Y‘, ‘%m/%d/%y‘] input_time_formats=None 格式列表:[‘%H:%M:%S‘, ‘%H:%M:%S.%f‘, ‘%H:%M‘] // FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 required=True, widget=None, label=None, initial=None, help_text=‘‘ // GenericIPAddressField protocol=‘both‘, both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 // SlugField(CharField) 数字,字母,下划线,减号(连字符) ... // UUIDField(CharField) uuid类型 ...
2)Django内置插件
TextInput(Input) NumberInput(TextInput) EmailInput(TextInput) URLInput(TextInput) PasswordInput(TextInput) HiddenInput(TextInput) Textarea(Widget) DateInput(DateTimeBaseInput) DateTimeInput(DateTimeBaseInput) TimeInput(DateTimeBaseInput) CheckboxInput Select NullBooleanSelect SelectMultiple RadioSelect CheckboxSelectMultiple FileInput ClearableFileInput MultipleHiddenInput SplitDateTimeWidget SplitHiddenDateTimeWidget SelectDateWidget
常用选择插件
// 单radio,值为字符串 user = fields.CharField( initial=2, widget=widgets.RadioSelect(choices=((1,‘上海‘),(2,‘北京‘),)) ) // 单radio,值为字符串 user = fields.ChoiceField( choices=((1, ‘上海‘), (2, ‘北京‘),), initial=2, widget=widgets.RadioSelect ) // 单select,值为字符串 user = fields.CharField( initial=2, widget=widgets.Select(choices=((1,‘上海‘),(2,‘北京‘),)) ) // 单select,值为字符串 user = fields.ChoiceField( choices=((1, ‘上海‘), (2, ‘北京‘),), initial=2, widget=widgets.Select ) // 多选select,值为列表 user = fields.MultipleChoiceField( choices=((1,‘上海‘),(2,‘北京‘),), initial=[1,], widget=widgets.SelectMultiple // 单checkbox user = fields.CharField( widget=widgets.CheckboxInput() ) // 多选checkbox,值为列表 user = fields.MultipleChoiceField( initial=[2, ], choices=((1, ‘上海‘), (2, ‘北京‘),), widget=widgets.CheckboxSelectMultiple )
在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。
方式一:
from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator class MyForm(Form): user = fields.ChoiceField( # choices=((1, ‘上海‘), (2, ‘北京‘),), initial=2, widget=widgets.Select ) def __init__(self, *args, **kwargs): super(MyForm,self).__init__(*args, **kwargs) # self.fields[‘user‘].widget.choices = ((1, ‘上海‘), (2, ‘北京‘),) # 或 self.fields[‘user‘].widget.choices = models.Classes.objects.all().value_list(‘id‘,‘caption‘)
方式二:
使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现
from django import forms from django.forms import fields from django.forms import widgets from django.forms import models as form_model from django.core.exceptions import ValidationError from django.core.validators import RegexValidator class FInfo(forms.Form): authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
自定义验证规则
方式一:
from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator class MyForm(Form): user = fields.CharField( validators=[RegexValidator(r‘^[0-9]+$‘, ‘请输入数字‘), RegexValidator(r‘^159[0-9]+$‘, ‘数字必须以159开头‘)], )
方式二:
import re from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.exceptions import ValidationError // 自定义验证规则 def mobile_validate(value): mobile_re = re.compile(r‘^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$‘) if not mobile_re.match(value): raise ValidationError(‘手机号码格式错误‘) class PublishForm(Form): title = fields.CharField(max_length=20, min_length=5, error_messages={‘required‘: ‘标题不能为空‘, ‘min_length‘: ‘标题最少为5个字符‘, ‘max_length‘: ‘标题最多为20个字符‘}, widget=widgets.TextInput(attrs={‘class‘: "form-control", ‘placeholder‘: ‘标题5-20个字符‘})) // 使用自定义验证规则 phone = fields.CharField(validators=[mobile_validate, ], error_messages={‘required‘: ‘手机不能为空‘}, widget=widgets.TextInput(attrs={‘class‘: "form-control", ‘placeholder‘: u‘手机号码‘})) email = fields.EmailField(required=False, error_messages={‘required‘: u‘邮箱不能为空‘,‘invalid‘: u‘邮箱格式错误‘}, widget=widgets.TextInput(attrs={‘class‘: "form-control", ‘placeholder‘: u‘邮箱‘}))
本文出自 “改变从每一天开始” 博客,请务必保留此出处http://lilongzi.blog.51cto.com/5519072/1906788
以上是关于Python自动化运维系列之Django Form表单验证的主要内容,如果未能解决你的问题,请参考以下文章
自动化运维系列之Ansible命令应用基础(模块的应用)持续更新中···