我想要做的是创建一个动态的 ModelForm,它会根据它的一个类属性生成额外的字段,以在 ModelAdmin 中使用。就像是:
class MyModelForm(forms.ModelForm):
config_fields = ('book_type', 'is_featured', 'current_price__is_sale')
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm
在这种情况下,MyModelForm 将通过执行一些自省来基于 config_fields 属性生成字段。到目前为止,我的方法看起来像这样(基于这个答案https://stackoverflow.com/a/6581949/677985):
class ConfigForm(type):
def __new__(cls, name, bases, attrs):
if 'config_fields' in attrs:
for config_field in attrs['config_fields']:
# ... (removed for clarity)
attrs.update(fields)
return type(name, bases, attrs)
class MyModelForm(forms.ModelForm):
__metaclass__ = ConfigForm
config_fields = ('book_type', 'is_featured', 'current_price__is_sale')
这种方法效果很好,但我对它不太满意,原因如下:
- 验证似乎不起作用,但目前这是一个小问题
- 我不太确定为什么需要“if config_field in attrs:”-condition,但它是
- 我希望 MyModelForm 继承而不是设置 __metaclass__ 属性,然后可以轻松重用基类,并允许我轻松覆盖 clean- 和 __init__- 方法。
我尝试实现第三项,结果是额外字段没有出现在管理表单中。如果有人可以帮助我解决这个问题,或者至少为我指出正确的方向,我将不胜感激。
我知道为此使用元类可能有点矫枉过正,并且猜测问题的一部分是 ModelForm 在其继承链中已经有一个或两个元类。因此,如果有人有替代解决方案来完成相同的任务,那会让我同样高兴。