指定与继承模型关联的ModelForm的初始字段值

时间:2011-02-02 14:15:24

标签: django django-forms model-inheritance

问题:如果使用模型继承并且每个子模型在呈现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中)。

我目前的做法

我目前正在做的是在Meta中存储初始值dict,并在我的视图中检查它。

# ----- 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={...} args,则使用默认值。

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"}

1 个答案:

答案 0 :(得分:1)

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

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

e.g。

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

class TestCommandForm(InitialModelForm):
    #form meta

class CompileCommandForm(InitialModelForm):
    #form meta