服务端假设所有用户提交的数据都是不可信任的,所以Django框架内置了form组件来验证用户提交的信息

form组件的2大功能:
       1 验证(显示错误信息)
       2 保留用户上次输入的信息
                  -- 可以生成html标签
应用:

class A_Form(Form):
               字段=fields.字段类型(默认参数:
                     required=True,
                      widget=widgets.插件(attrs={}))

           常用字段:Charfield,RegexField,IntegerField,EmailField
           常用参数:max_length,min_length,
                     widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'))
                     error_messages={
                         'required':'用户名不能为空',
                         'max_length':'太长了',
                         'min_length':'太短了',
                               }
                     label='用户名',  # obj.t1.label
             disabled=False,              # 是否可以编辑
             label_suffix='--->',            # Label内容后缀
                 help_text='。。。。。。',  # 提供帮助信息
        

      obj=A_Form(initial='')#生成空的html标签,含有默认值
      

      obj=A-Form(request.POST)#拿到浏览器请求,传入form做验证
      obj.is_valid()#判断验证是否通过
      obj.cleaned_data()#验证通过后的值  字典形式
      obj.errors   #form 返回的错误信息  是个对象   'obj.errors.字典.0 ' 获取第一个错误信息

 

 原理: 

    1 LoginForm实例化时:self.fields={
                       'username':正则表达式
                       'password':正则表达式}
    2 循环self.fields
        flag=True
        errors
        cleaned_data
        for k,v in self.fields.items():
              username ,正则
              input_value=request.POST.get(k)
              input_value,正则
              flag=false /true
        return flag

 

ModelForm
    a.  class Meta:
            model,                           # 对应Model的
            fields=None,                     # 字段
            exclude=None,                    # 排除字段
            labels=None,                     # 提示信息
            help_texts=None,                 # 帮助提示信息
            widgets=None,                    # 自定义插件
            error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
            field_classes=None               # 自定义字段类 (也可以自定义字段)
            localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
            如:
                数据库中
                    2016-12-27 04:10:57
                setting中的配置
                    TIME_ZONE = 'Asia/Shanghai'
                    USE_TZ = True
                则显示:
                    2016-12-27 12:10:57
    b. 验证执行过程
        is_valid -> full_clean -> 钩子 -> 整体错误
 
    c. 字典字段验证
        def clean_字段名(self):
            # 可以抛出异常
            # from django.core.exceptions import ValidationError
            return "新值"
    d. 用于验证
        model_form_obj = XXOOModelForm()
        model_form_obj.is_valid()
        model_form_obj.errors.as_json()
        model_form_obj.clean()
        model_form_obj.cleaned_data
    e. 用于创建
        model_form_obj = XXOOModelForm(request.POST)
        #### 页面显示,并提交 #####
        # 默认保存多对多
            obj = form.save(commit=True)
        # 不做任何操作,内部定义 save_m2m(用于保存多对多)
            obj = form.save(commit=False)
            obj.save()      # 保存单表信息
            obj.save_m2m()  # 保存关联多对多信息
 
    f. 用于更新和初始化
        obj = model.tb.objects.get(id=1)
        model_form_obj = XXOOModelForm(request.POST,instance=obj)
        ...
 
        PS: 单纯初始化
            model_form_obj = XXOOModelForm(initial={...})

 

 扩展:

   

      1.由于form组件中每个字段都是类的数据属性(全局变量),在类每次实例化之后,数据属性不会发生改变,会保留上次的更新结果
           导致无法动态显示数据库的内容

解决方法一:每次实例化之前,更新xx字段的值
     xx=fields.MultipleChoiceField(
        # choices=models.Classes.objects.values_list('id','title'),
        widget=widgets.SelectMultiple
      )

    def __init__(self,*args,**kwargs):
        super(TeacherForm,self).__init__(*args,**kwargs)
        self.fields['xx'].choices=models.Classes.objects.values_list('id','title')
   
    解决方法二:不推荐
     from django.forms import models as form_model
     xx=form_model.ModelMultipleChoiceField(queryset=models.Classes.objects.all())

      models中:
       def __str__(self):
           return self.title

 

 2. 扩展字段

单选:ChoiceField
          多选:MultipleChoiceField
                    Select框:
            单选
                            cls_id = fields.IntegerField(
                        # widget=widgets.Select(choices=[(1,'上海'),(2,'北京')])
                        widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'))
                    )
                    
                    cls_id = fields.ChoiceField(
                        choices=models.Classes.objects.values_list('id','title'),
                        widget=widgets.Select(attrs={'class': 'form-control'})
                    )
                    
                    
                    obj = FooForm({'cls_id':1})
            多选
                    xx = fields.MultipleChoiceField(
                        choices=models.Classes.objects.values_list('id','title'),
                        widget=widgets.SelectMultiple
                    )
                    
                    obj = FooForm({'cls_id':[1,2,3]})
          文件:FileField

 

 常用选择插件

 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 # )
View Code

相关文章: