您可以使用多重继承又名混入,以计算Form和ModelForm中使用的字段。
class SwallowFormFields:
airspeed_velocity = forms.IntegerField(...)
is_migratory = forms.BooleanField(...)
class AfricanSwallowForm(forms.ModelForm, SwallowFormFields):
class Meta:
model = AfricanBird
class EuropeanSwallowForm(forms.Form, SwallowFormFields):
pass
UPDATE:
因为这不符合Django的元编程工作,您可能需要创建一个自定义__init__
构造,增加了继承的字段对象的字段列表,也可以明确添加引用
class SwallowFormFields:
airspeed_velocity = forms.IntegerField()
is_migratory = forms.BooleanField()
class AfricanSwallowForm(forms.ModelForm):
airspeed_velocity = SwallowFormFields.airspeed_velocity
is_migratory = SwallowFormFields.is_migratory
class Meta:
model = AfricanSwallow
class EuropeanSwallowForm(forms.Form):
airspeed_velocity = SwallowFormFields.airspeed_velocity
is_migratory = SwallowFormFields.is_migratory
UPDATE:
的类定义中
当然,你不必巢共享领域成为一类 - 你也可以简单地将它们定义为全局...
airspeed_velocity = forms.IntegerField()
is_migratory = forms.BooleanField()
class AfricanSwallowForm(forms.ModelForm):
airspeed_velocity = airspeed_velocity
is_migratory = is_migratory
class Meta:
model = AfricanSwallow
class EuropeanSwallowForm(forms.Form):
airspeed_velocity = airspeed_velocity
is_migratory = is_migratory
UPDATE:
好吧,如果你真的想干最大的,你必须去metaclasses。
因此,这里是你如何可以做到这一点:
from django.forms.models import ModelForm, ModelFormMetaclass
from django.forms.forms import get_declared_fields, DeclarativeFieldsMetaclass
from django.utils.copycompat import deepcopy
class MixinFormMetaclass(ModelFormMetaclass, DeclarativeFieldsMetaclass):
def __new__(cls, name, bases, attrs):
# default __init__ that calls all base classes
def init_all(self, *args, **kwargs):
for base in bases:
super(base, self).__init__(*args, **kwargs)
attrs.setdefault('__init__', init_all)
# collect declared fields
attrs['declared_fields'] = get_declared_fields(bases, attrs, False)
# create the class
new_cls = super(MixinFormMetaclass, cls).__new__(cls, name, bases, attrs)
return new_cls
class MixinForm(object):
__metaclass__ = MixinFormMetaclass
def __init__(self, *args, **kwargs):
self.fields = deepcopy(self.declared_fields)
现在,您可以派生formfields集合来自MixinForm这样的:
class SwallowFormFields(MixinForm):
airspeed_velocity = forms.IntegerField()
is_migratory = forms.BooleanField()
class MoreFormFields(MixinForm):
is_endangered = forms.BooleanField()
然后将它们添加到基类,如清单这个:
class EuropeanSwallowForm(forms.Form, SwallowFormFields, MoreFormFields):
pass
class AfricanSwallowForm(forms.ModelForm, SwallowFormFields):
class Meta:
model = AfricanSwallow
那么它是做什么的?
- 元类收集在你的MixinForm声明的所有字段
- 然后添加自定义
__init__
构造,确保了MixinForm的__init__
方法被称为神奇。 (否则你必须明确地调用它。)
MixinForm.__init__
份声明的字段诠释领域属性
请注意,我既不是Python的用户,也不是Django的开发人员,并且元类是危险的。所以如果你遇到奇怪的行为更好地坚持以上更详细的方法:)
祝你好运!
起初,我看着这个并将其解散,认为它很常规,但对于现实世界的使用来说太笨拙了。第二次阅读后,我意识到这是一个很棒的方法。它完美地工作,并且足够可读,并带有一些额外的评论。 – jMyles 2011-03-03 20:32:34