博客
关于我
Django Form组件
阅读量:614 次
发布时间:2019-03-12

本文共 8442 字,大约阅读时间需要 28 分钟。

文章目录

使用Form组件验证

views:

from django.shortcuts import render, HttpResponsefrom django import forms# 先定义一个Form类class LoginForm(forms.Form):    name = forms.CharField(        label='用户名',        initial='陌生人',        strip=True,        error_messages={               'required': '用户名不能为空',        }    )    # 密码框    password = forms.CharField(        label='密码',        min_length=6,        widget=forms.PasswordInput(render_value=True),        error_messages={               'required': '密码不能为空',            'min_length': '密码不能小于6位',        }    )    # 单选框    gender = forms.ChoiceField(        choices=[(1, '男'), (2, '女'), (3, '保密')],        label='性别',        initial=3,        widget=forms.RadioSelect(),        error_messages={               'required': '请选择性别'        }    )    # 下拉单选    hobby = forms.ChoiceField(        label='爱好',        widget=forms.Select(),        choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')),        initial=2,    )    # 多选    hobby2 = forms.MultipleChoiceField(        label='爱好2',        choices=((1, '摩托车'), (2, '汽车'), (3, '游艇')),        initial=[1, 3],        widget=forms.SelectMultiple()    )    # 单选checkbox    keep = forms.ChoiceField(        label='是否记住密码',        initial='checked',        widget=forms.CheckboxInput()    )    # 多选checkbox    city = forms.ChoiceField(        label='居住城市',        choices=[(1, '北京'), (2, '天津'), (3, '上海'), (4, '武汉')],        initial=4,        widget=forms.Select()    )# 写一个函数视图def login(request):    form_obj = LoginForm()    if request.method == 'POST':        form_obj = LoginForm(request.POST)        if form_obj.is_valid():            pass    return render(request, 'app/login.html', {   'form_obj': form_obj})

templates:

{% csrf_token %}

{ { form_obj.name }} { { form_obj.name.errors.0 }}

{ { form_obj.password }} { { form_obj.password.errors.0 }}

{ { form_obj.gender }} { { form_obj.gender.errors.0 }}

{ { form_obj.hobby }} { { form_obj.hobby.errors.0 }}

{ { form_obj.hobby2 }} { { form_obj.hobby2.errors.0 }}

{ { form_obj.keep }} { { form_obj.keep.errors.0 }}

{ { form_obj.city }} { { form_obj.city.errors.0 }}

常用Form组件内置字段

Field    required=True,               是否允许为空    widget=None,                 HTML插件    label=None,                  用于生成Label标签或显示内容    initial=None,                初始值    help_text='',                帮助信息(在标签旁边显示)    error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}    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,              最小值DecimalField(IntegerField)    max_value=None,              最大值    min_value=None,              最小值    max_digits=None,             总长度    decimal_places=None,         小数位长度 DateField(BaseTemporalField)    格式:2015-09-01TimeField(BaseTemporalField)    格式:11:12DateTimeField(BaseTemporalField)格式:2015-09-01 11:12  RegexField(CharField)    regex,                      自定制正则表达式    max_length=None,            最大长度    min_length=None,            最小长度    error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}ChoiceField(Field)    choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)    required=True,             是否必填    widget=None,               插件,默认select插件    label=None,                Label内容    initial=None,              初始值    help_text='',              帮助提示

字段校验

RegexValidator验证器

from django.core.validators import RegexValidatorno = forms.CharField(    label='员工编号',    validators=[RegexValidator(r'^[0-9]+', '请输入数字'), RegexValidator('^110[0-9]+$', '请以110开头')])

自定义函数验证

import refrom django.core.exceptions import ValidationErrordef mobile_validate(value):    mobile_re = re.compile(r'^1[2356789]{1}[0-9]{9}$')    if not mobile_re.match(value):        raise ValidationError('手机号格式错误')class LoginForm(forms.Form):     mobile = forms.CharField(        label='手机号',        validators=[mobile_validate, ],        error_messages={               'required': '手机号不能为空',        }    )

Hook方法

局部钩子

在Fom类中定义 clean_字段名()方法,就能够实现对特定字段进行校验

class LoginForm(forms.Form):      description = forms.CharField(        label='内容描述',        initial='暂无描述',        min_length=4,        error_messages={               'required': '不能为空',            'invalid': '格式错误',            'min_length': '最少评论4个字'        }    )    def clean_description(self):        value = self.cleaned_data.get('description')        if '666' in value:            raise ValidationError('请不要喊666')        else:            return value

全局钩子

在Fom类中定义clean()方法,就能够实现对字段进行全局校验

class LoginForm(forms.Form):    # 密码框    password = forms.CharField(        label='密码',        min_length=6,        widget=forms.PasswordInput(),        error_messages={               'required': '密码不能为空',            'min_length': '密码不能小于6位',        }    )    repassword = forms.CharField(        label='请再次输入密码',        min_length=6,        widget=forms.PasswordInput(),        error_messages={               'required': '密码不能为空',            'min_length': '密码不能小于6位',        }    )    def clean(self):        password_value = self.cleaned_data.get('password')        repassword_value = self.cleaned_data.get('repassword')        if password_value == repassword_value:            return self.cleaned_data        else:            self.add_error('repassword', '两次密码不一致')

源码分析

  1. 在执行form_obj.is_valid()进行判断

  2. 进入is_valid方法

    def is_valid(self):    """        Returns True if the form has no errors. Otherwise, False. If errors are        being ignored, returns False.        """    return self.is_bound and not self.errors

    self.is_bound判断是否有数据

    self.errors判断是否有错误信息

  3. 进入errors属性方法

    @propertydef errors(self):    "Returns an ErrorDict for the data provided for the form"    if self._errors is None:        self.full_clean()        return self._errors
  4. 进入full_clean方法

    self._errors存放错误信息

    cleaned_data存放验证通过的数据

    def full_clean(self):    """        Cleans all of self.data and populates self._errors and        self.cleaned_data.        """    self._errors = ErrorDict()    if not self.is_bound:  # Stop further processing.        return    self.cleaned_data = {     }    # If the form is permitted to be empty, and none of the form data has    # changed from the initial data, short circuit any validation.    if self.empty_permitted and not self.has_changed():        return    self._clean_fields()    self._clean_form()    self._post_clean()
  5. 执行_clean_fields方法,循环每个字段,分别校验

    def _clean_fields(self):    for name, field in self.fields.items():        # value_from_datadict() gets the data from the data dictionaries.        # Each widget type knows how to retrieve its own data, because some        # widgets split data over several HTML fields.        if field.disabled:            value = self.get_initial_for_field(field, name)            else:                value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))                try:                    if isinstance(field, FileField):                        initial = self.get_initial_for_field(field, name)                        value = field.clean(value, initial)                        else:                            value = field.clean(value)                            self.cleaned_data[name] = value                            if hasattr(self, 'clean_%s' % name):                                value = getattr(self, 'clean_%s' % name)()                                self.cleaned_data[name] = value                                except ValidationError as e:                                    self.add_error(name, e)
  6. 执行_clean_form方法

    def _clean_form(self):    try:        cleaned_data = self.clean()    except ValidationError as e:        self.add_error(None, e)    else:        if cleaned_data is not None:            self.cleaned_data = cleaned_data

转载地址:http://vwhxz.baihongyu.com/

你可能感兴趣的文章
C/C++中的字符串4个库函数
查看>>
201604-4 游戏 ccf
查看>>
1144. The Missing Number (20)
查看>>
Java之StringUtils的常用方法
查看>>
为什么阿里巴巴不建议在for循环中使用”+”进行字符串拼接
查看>>
【Spring Boot 26】分别在SpringBoot和Vue中解决跨域问题
查看>>
Class.forName(),classloader.loadclass用法详解
查看>>
tp5.1 页面错误!请稍后再试~ 安装好后,提示错误
查看>>
查看Nginx 服务器 php错误日志log
查看>>
php if条件 switch
查看>>
阿里云 安全组规则 设置某个IP不能访问服务器(出站)
查看>>
表示换行
查看>>
JS调用新闻
查看>>
取得刚刚添加记录的ID
查看>>
系统打了补丁后,IIS装不了的解决…
查看>>
Dreamweaver自适应客户端分辨率的…
查看>>
没有找到framedyn.dll,因此这个应…
查看>>
XP SP3无法安装IIS的解决办法
查看>>
超链接如何加下划线
查看>>
禁止重复提交(JavaScript控制表单…
查看>>