zoukankan      html  css  js  c++  java
  • 自定义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)











































  • 相关阅读:
    Oracle Drop表并未直接删除 drop table xx purge
    Notepad++使用
    Python使用MySQL数据库
    考驾照科目二科目三要点记录
    Linux中权限(r、w、x)对于目录与文件的意义
    linux之expr命令
    linux下scp
    数字货币和区块链联系
    网站
    关于linux 编程
  • 原文地址:https://www.cnblogs.com/52forjie/p/8533651.html
Copyright © 2011-2022 走看看