2010-07-04 76 views
2

我想我終於明白他們需要使用這個DeclarativeFieldsMetaclass(將類字段轉換爲實例變量並使用有序/排序的字典來維護它們的順序)。但是,我仍然不太確定爲什麼他們選擇使用BaseForm而不是直接在Form類中實現所有內容?爲什麼Django使用BaseForm?

他們left a comment

class Form(BaseForm): 
    "A collection of Fields, plus their associated data." 
    # This is a separate class from BaseForm in order to abstract the way 
    # self.fields is specified. This class (Form) is the one that does the 
    # fancy metaclass stuff purely for the semantic sugar -- it allows one 
    # to define a form using declarative syntax. 
    # BaseForm itself has no way of designating self.fields. 

但我並不真正瞭解它。 「爲了抽象self.fields被指定的方式」 - 但是Python在Form.__init__之前調用DeclarativeFieldsMetaclass.__new__,所以他們可以按照原樣在Form.__init__之內充分利用self.fields;爲什麼他們需要一個額外的抽象層?

回答

0

來源:

class MetaForm(type): 
    def __new__(cls, name, bases, attrs): 
     print "%s: %s" % (name, attrs) 
     return type.__new__(cls, name, bases, attrs) 

class BaseForm(object): 
    my_attr = 1 
    def __init__(self): 
     print "BaseForm.__init__" 

class Form(BaseForm): 
    __metaclass__ = MetaForm 
    def __init__(self): 
     print "Form.__init__" 

class CustomForm(Form): 
    my_field = 2 
    def __init__(self): 
     print "CustomForm.__init__" 

f = CustomForm() 

輸出:

Form: {'__module__': '__main__', '__metaclass__': <class '__main__.MetaForm'>, '__init__':<function __init__ at 0x0227E0F0>} 
CustomForm: {'__module__': '__main__', 'my_field': 2, '__init__': <function __init__ at 0x0227E170>} 
CustomForm.__init__ 

貌似MetaForm.__new__被調用了兩次。一次爲Form,一次爲CustomForm,但從未爲BaseForm。通過擁有一個乾淨的(空的)Form類,不會有任何無關的屬性循環。這也意味着你可以在BaseForm裏面定義Fields這可以用於內部使用,但是避免渲染。

2

我認爲原因是SIMPL,電子與BaseForm只有你可以使用decalrative語法即

class MyForm(Form): 
    field_xxx = form.TextField(...) 
    field_nnn _ form.IntegerField(...) 

對於這樣的東西的工作了應該有一個元類DeclarativeFieldsMetaclass這在形式上是隻設置爲不定義字段,他們這樣做是因爲

這是基本形式 抽象一個單獨的類以的方式, self.fields是specifie

所以現在你可以寫WierdForm類,其中可以用一些更奇怪的方式來定義字段。將params傳遞給類對象,要點是所有的API都在BaseFormForm類中只是提供了一個易於定義的字段。

摘要:IMO django傾向於引入另一層,以便在需要時可以實現不同類型的字段聲明,至少它可以將窗體的非核心功能分開。

+0

這就是我的觀點,*是的,你可以*。你不需要額外的層來實現這個「聲明式語法」。我知道,因爲我自己做了,現在我在思考爲什麼Django決定以不同的方式做。我甚至不確定使用元類是完全必要的,儘管這樣做可能更乾淨更加pythonic。 「將params傳遞給類對象」意味着什麼? - 是否將'WeirdForm(Form)'賦給'__init__'方法?這不會阻止調用「BaseForm .__ init__」嗎?如果不是,那就是我的答案。 – mpen 2010-07-05 05:33:11

+0

剛剛嘗試過。在您的'WeirdSubForm'中添加'__init__'方法會跳過對'BaseForm .__ init__'的調用(除非明確調用),否則也不能這樣。 – mpen 2010-07-05 05:37:12

+0

哦......只是想到了這個......也許它是效率/未來兼容性的東西?如果你保持'Form'爲空,那麼'DeclarativeFieldsMetaclass .__ new__'只需遍歷你定義的字段,而不是'BaseForm'中所有額外的垃圾?理論上講,你可以將實際的'Fields'添加到'BaseForm',而不是將它們添加到'fields'集合中。除非'__new__' *中的'attrs'包含'BaseForm' attrs,因爲它是派生的......我必須測試這個。 – mpen 2010-07-05 05:42:14

相關問題