zoukankan      html  css  js  c++  java
  • Form 源码

    1. is_valid如果返回值如果为真 证明验证成功 意味着self.is_bound为True 和 self.errors为False
    
    	def is_valid(self):
    	    return self.is_bound and not self.errors
    
    	    1).那么self.is_bound什么时候为真呢? 通过源码发现只有当实例化带参数的值时 self.is_bound 才为真 默认会把传入的值赋值给data data有值时 self.is_bound为真
    	    2).那么self.errors什么时候为假呢?  请看下面
    
    2. 类初始化时候self._errors为None  所以此时会执行 self.full_clean()
    
    	@property
    	def errors(self):
    	    
    	    if self._errors is None:
    	        self.full_clean()
    	    return self._errors
    
    
    3. 这部分代码的 最后生成 self.cleaned_data = {} 然后分别执行底下三个方法
    
    	def full_clean(self):
    
    	    self._errors = ErrorDict()
    
    	    # 当用户提交数据时self.is_bound为真  not Ture代为为假  所以这部分不执行
    	    if not self.is_bound:  
    	        return
    
    	    # 创建一个 {}
    	    self.cleaned_data = {}
    
    	    if self.empty_permitted and not self.has_changed():
    	        return
    	    
    	    # 循环验证字段和字段对应的值 和钩子函数 如果验证成功 把字段和字段对应的值加入到self.cleand_data里面 错误会加入到self.errors里面
    	    self._clean_fields()
    
    	    # 执行self.clean()函数 默认返回self.cleaned_data  可以在子类中子定义self.clean() 方法 
    	    self._clean_form()
    
        	self._post_clean()
    
    4.  循环类里面的字段 如果验证成功 将字段名和值 加入self.cleaned_data  例如: self.cleaned_data = {'username': 'alex'}
    	接着会找clean_字段名 的钩子函数,如果有此函数例如clean_username(),会执行此函数,并把结果覆盖 self.cleaned_data = {'username': 结果}
    	当循环完 username 会循环 password 
    
    	def _clean_fields(self):
    	    for name, field in self.fields.items():
    	        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)
    
    	            # 将name和value增加到 self.cleaned_data 字典里面
    	            self.cleaned_data[name] = value
    
    	            # 判断有没有 clean_字段 的函数 如果有 会覆盖上面self.cleaned_data对应的值
    	            if hasattr(self, 'clean_%s' % name):
    	                value = getattr(self, 'clean_%s' % name)()
    	                self.cleaned_data[name] = value
    	        except ValidationError as e:
    	        	# 如果验证错误 会把错误信息 加入到self.errors里面
    	            self.add_error(name, e)
    

      

    - is_valid
    	- 字段 = 默认正则表达式
    		 - 额外的正则
    			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开头')],
    			)
    	- clean_字段,必须返回值
    	- clean()  
    		有返回值:cleaned_data = 返回值
    		无返回值:cleaned_data = 原来的值
    

      

    from django.core.exceptions import ValidationError
    class TestForm(Form):
        user = fields.CharField(validators=[])
        pwd = fields.CharField()
    
    
    
        #对单个字段做验证
        def clean_user(self):
            v = self.cleaned_data['user']
            if models.Student.objects.filter(name=v).count():
                raise ValidationError('用户名已经存在')
            return self.cleaned_data['user']
    
        def clean_pwd(self):
            return self.cleaned_data['pwd']
    
    
        #对整体所有的值做验证,如果数据库有值,抛异常
        def clean(self):
            user = self.cleaned_data.get('user')
            email = self.cleaned_data.get('email')
            if models.Student.objects.filter(user=user,email=email).count():
                raise ValidationError('用户名和邮箱联合已经存在')
            return self.cleaned_data
    
        def _post_clean(self):
            """
            An internal hook for performing additional cleaning after form cleaning
            is complete. Used for model validation in model forms.
            """
            pass
    

      

  • 相关阅读:
    About Spring
    execle导入后 数据 无刷新 显示在 输入页面
    前端小神龟 -- 分页导航栏
    如何在mysql命令窗口获取到程序正在执行的sql语句
    div+css(ul li)实现图片上文字下列表布局
    C#异常之(已有打开的与此 Command 相关联,已有打开的与此命令相关联的 DataReader,必须首先将它关闭。)
    台灣VR內容產業聯盟_技術推廣中心
    2014新的一年到来,祝大家新年快乐
    matlab 提取文件路径名称,用于实现遍历读取文件(我的目的是遍历图像)
    无监督学习一些算法的简要概括(一)-稀疏自编码
  • 原文地址:https://www.cnblogs.com/golangav/p/7163849.html
Copyright © 2011-2022 走看看