问题:如果使用模型继承并且每个子模型在渲染ModelForm
.
以以下模型为例,其中CompileCommand
和TestCommand
两者在呈现为时都需要不同的初始值ModelForm
。
# ------ models.py
class ShellCommand(models.Model):
command = models.Charfield(_("command"), max_length=100)
arguments = models.Charfield(_("arguments"), max_length=100)
class CompileCommand(ShellCommand):
# ... default command should be "make"
class TestCommand(ShellCommand):
# ... default: command = "make", arguments = "test"
我知道initial={...}
在实例化表单时可以使用该参数,但是我宁愿将初始值存储在模型的上下文中(或至少在关联的 ModelForm 中)。
我目前的做法
我现在正在做的是在 dict 中存储一个初始值Meta
,并在我的视图中检查它。
# ----- forms.py
class CompileCommandForm(forms.ModelForm):
class Meta:
model = CompileCommand
initial_values = {"command":"make"}
class TestCommandForm(forms.ModelForm):
class Meta:
model = TestCommand
initial_values = {"command":"make", "arguments":"test"}
# ------ in views
FORM_LOOKUP = { "compile": CompileCommandFomr, "test": TestCommandForm }
CmdForm = FORM_LOOKUP.get(command_type, None)
# ...
initial = getattr(CmdForm, "initial_values", {})
form = CmdForm(initial=initial)
这感觉太像黑客了。我渴望一种更通用/更好的方法来实现这一点。建议表示赞赏。
更新的解决方案(看起来很有希望)
我现在有以下内容forms.py
,允许我Meta.default_initial_values
在视图中设置而不需要额外的样板代码。如果用户未指定initial={...}
参数,则使用默认值。
class ModelFormWithDefaults(forms.ModelForm):
def __init__(self, *args, **kwargs):
if hasattr(self.Meta, "default_initial_values"):
kwargs.setdefault("initial", self.Meta.default_initial_values)
super(ModelFormWithDefaults, self).__init__(*args, **kwargs)
class TestCommandForm(ModelFormWithDefaults):
class Meta:
model = TestCommand
default_initial_values = {"command":"make", "arguments":"test"}