284 Tornado【第2篇】:Tornado自定義Form元件
一、獲取類裡面的靜態屬性以及動態屬性的方法
方式一:
# ===========方式一================ class Foo(object): user = 123 def __init__(self): self.name = 123 self.age = 456 def aaa(self): self.name = 'sd' obj = Foo() # print(obj.__dict__) #獲取物件屬性 # print(Foo.__dict__) #獲取類裡面的所有屬性以及方法等
方式二:
#===============方式二================== class Foo2(object): A = 123 def __init__(self): self.name = 'haiyan' self.age = 22 # print(self.__class__.field) #獲取當前類的 def __new__(cls, *args, **kwargs): print(cls.__dict__) return object.__new__(cls)Foo2()
二、自定義Form元件示例
import re import copy class ValidateError(Exception) : '''自定義異常''' def __init__(self,detail): self.detail = detail# =自定義外掛=====
class TextInput(object):
def str(self):
return '<input type="text">'class EmailInput(object):
def str(self):
return '<input type="email">'# 欄位:內部包含正則用於驗證==========
class Field(object):
def init(self,required=True,error_message=None, widgets= None):
self.required = required
self.error_message = error_message
if not widgets:
self.widgets = TextInput() #設定預設
else:
self.widgets = widgets</span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__str__</span><span style="color: rgba(0, 0, 0, 1)">(self): </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> return self.widgets</span> <span style="color: rgba(0, 0, 255, 1)">return</span> str(self.widgets) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">將物件轉成字串</span>
class CharField(Field):
</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> valid(self,val): </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> self.required: </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> val: msg </span>= self.error_message[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">required</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">] </span><span style="color: rgba(0, 0, 255, 1)">raise</span> ValidateError(msg) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">呼叫自定義的異常</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> val
class EmailField(Field):
ERG = "^\w+@\w+$"
def valid(self,val):
if self.required:
if not val:
msg = self.error_message['required']
raise ValidateError(msg)
# print(val, type(val))
result = re.match(self.ERG,val)
if not result:
msg = self.error_message.get('invalid','格式錯誤')
raise ValidateError(msg)
return val# ==========================
class Form(object):
def init(self,data):
# print(UserForm.dict)#獲取派生類中的所有靜態欄位
# print(self.class.dict) #靜態動態的獲取類中的所有靜態欄位
self.data = data
self.fields = copy.deepcopy(self.class.declare_field) #獲取欄位
self.clean_data = {}
self.errors = {}
def new(cls, *args, **kwargs): #在__new__裡面也可以獲取類中的所有靜態欄位
declare_field = {}
for field_name , field in cls.dict.items():
# print(field_name,field)
if isinstance(field,Field):
declare_field[field_name] = field
cls.declare_field = declare_field
return object.new(cls) #建立物件<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> is_valid(self): </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">使用者提交的資料</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> self.data #{'username':"zzz","pwd":18}</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> self.fields #{'username': CharField(),"pwd": EmailField()}</span> <span style="color: rgba(0, 0, 255, 1)">for</span> field_name , field <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> self.fields.items(): </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">: input_val </span>=<span style="color: rgba(0, 0, 0, 1)"> self.data.get(field_name) </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print("---------------",field_name,input_val)</span> val = field.valid(input_val) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">內建的驗證規則自己去驗證</span> method = getattr(self,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">clean_%s</span><span style="color: rgba(128, 0, 0, 1)">"</span>%field_name,None) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">預設為None</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> method: val </span>=<span style="color: rgba(0, 0, 0, 1)"> method(val) self.clean_data[field_name] </span>=<span style="color: rgba(0, 0, 0, 1)"> val </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> ValidateError as e: self.errors[field_name] </span>=<span style="color: rgba(0, 0, 0, 1)"> e.detail </span><span style="color: rgba(0, 0, 255, 1)">return</span> len(self.errors) ==0 <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">根據錯誤的返回,如果沒有錯誤返回True,有錯誤返回False</span> <span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__iter__</span>(self): <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">#########自定義生成標籤3</span> <span style="color: rgba(0, 0, 255, 1)">return</span> iter(self.fields.values()) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">返回的是一個迭代器</span>
# =======================
class UserForm(Form):
username = CharField(error_message={'required': '使用者名稱不能為空'}, widgets=TextInput())
# email = EmailField(error_message={'required': '密碼不能為空', 'invalid': '郵箱格式錯誤'}, widgets=EmailInput())
obj = UserForm(data={'username':"haiyan","email":"dsfsgd"})
if obj.is_valid():
print(obj.clean_data)
else:
print(obj.errors)