自定义form

一:form组件分为三类设计思想

 设计思想:

      插件
字段
    Form

流程:
PS:按照结果反推流程

1,按照内置的form组件,首先会先继承Form,并且静态字段是继承Charfield类
class UserForm(Form):
    name=Charfield(errormsg={'required':'用户名不能为空'},widget=Textinput())
    pwd=Emialfield(errormsg={'required':'密码不能为空'})

 2,定义Form组件,让UserForm继承

要实现的功能:

1):找到userform的静态字段     PS:通过userform的__dict__方式.

2):找到静态字段后,要获取字段里面的结构     PS:字段继承哪个类,显示方式,客户填入的数据

3):判断客户输入的数据符合要求 字段格式的要求    PS:比如Charfield()的格式  比如 空字符,有正则匹配的

4):校验数据,并把所有的内容放入 cleaned_data里面    PS:还要注意是否有钩子函数,如果有钩子函数,那么数据一定要先通过钩子函数验证过才行.

5):如果数据错误,需要把错误信息放到error表中

6):最后字段在html页面的显示.  通过__iter__方法,把对象变成迭代器,一一生成,                  PS:这里就需要在另外写不同的类创建不同的html格式

 

总结:

Form类,是整个组件的中枢,他负责调动整个组件需求,除了自己的主要功能,别的零散需求则分配给下面的   字段和组件做

字段(Charfield)负责每个字段的显示

插件field则分配html页面的显示功能

 

3,上简单代码

class Textinput(object):
    def __str__(self):
        return "12"

class Field(object):
    def __init__(self, required=None, invalid=None, errormsg=None,widget=None):
        self.msg = None
        self.errormsg = errormsg
        self.widget=widget
        if not self.widget:
            self.widget=Textinput()

        else:
            self.widget=widget
    def __str__(self):
        return str(self.widget)  #这里一定要加上str



class Emialfield(Field):
    def valid(self, val):
        if self.errormsg:
            for msg in self.errormsg:
                if msg == 'required':
                    if not val:
                        self.msg = self.errormsg['required']
                        raise Exception(self.msg)
        return val


class Charfield(Field):


    def valid(self,val):
        # if self.required:
        # if self.errormsg:
        #     if not val:         #这里面可以进行
        #         self.errormsg=self.errormsg[self.required]
        #         raise Exception(self.errormsg)
        #
        if self.errormsg:
            for msg in self.errormsg:
                if msg=='required':
                    if not val:
                        self.msg=self.errormsg['required']
                        raise Exception(self.msg)
        return val

import copy
class Form(object):

    def __init__(self,data):
        self.data=data
        self.field_dct=copy.deepcopy(self.__class__.field_dct)
        self.cleaned_data={}
        self.errmsg={}



    def __new__(cls, *args, **kwargs):
        dct={}
        for key,field in cls.__dict__.items():
            if isinstance(field,Field):
                #找到所有的静态字段
                dct[key]=field
        cls.field_dct=dct

        return super().__new__(cls)

    def is_valid(self):
        for key,field in self.field_dct.items():
            try:

                value=field.valid(self.data.get(key,None))
                self.cleaned_data[key]=value

            except Exception as e:
                self.errmsg[key]=str(e)

        return len(self.errmsg)==0

    def __iter__(self):
        return iter(self.field_dct.values())

class UserForm(Form):
    name=Charfield(errormsg={'required':'用户名不能为空'},widget=Textinput())
    pwd=Emialfield(errormsg={'required':'密码不能为空'})

obj=UserForm(data={'name':'alex','pwd':123})
if obj.is_valid():

    print(obj.cleaned_data)
else:
    print(obj.errmsg)


for i in obj:
    print(i)

 

 

 

 

 












































posted @ 2018-03-09 14:17  forjie  阅读(195)  评论(0编辑  收藏  举报