我想我终于想通了他们需要使用这个DeclarativeFieldsMetaclass
(将类字段转换为实例变量并使用有序/排序的字典维护它们的顺序)。但是,我仍然不确定为什么他们选择使用BaseForm
而不是直接在Form
类中实现所有内容?
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在DeclarativeFieldsMetaclass.__new__
之前调用Form.__init__
,因此他们可以充分利用self.fields
内的Form.__init__
作为是;为什么他们需要额外的抽象层?
答案 0 :(得分:2)
我认为理由是简单的,仅凭BaseForm
,您无法使用decalrative语法定义字段,即
class MyForm(Form):
field_xxx = form.TextField(...)
field_nnn _ form.IntegerField(...)
对于这样的工作,应该有一个仅在Form中设置的元类DeclarativeFieldsMetaclass
,他们这样做是因为
这是一个与BaseForm不同的类 为了抽象的方式, self.fields是特定的
所以现在你可以编写WierdForm类,其中可以定义的字段可能是以某种奇怪的方式,例如将params传递给类对象,点是BaseForm
中的所有API,Form
类只提供一个易于定义的字段。
摘要:IMO django倾向于引入另一个层,以便在需要时可以实现不同类型的字段声明,至少它可以使表单的非核心功能保持独立。
答案 1 :(得分: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
类,循环不会有任何无关的属性。这也意味着您可以在Fields
中定义可用于内部使用的BaseForm
,但避免渲染。