2

问题:如果使用模型继承并且每个子模型在渲染ModelForm.

以以下模型为例,其中CompileCommandTestCommand两者在呈现为时都需要不同的初始值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"}
4

1 回答 1

1

如果您必须发送到表单 init,我认为在表单的元数据上设置 initial_values 并没有多大用处。

我宁愿创建一个覆盖构造函数方法的 ModelForm 子类,然后将该子类用作其他表单的父类。

例如

class InitialModelForm(forms.ModelForm):
    #here you override the constructor
    pass

class TestCommandForm(InitialModelForm):
    #form meta

class CompileCommandForm(InitialModelForm):
    #form meta
于 2011-02-02T15:08:59.063 回答