質問: モデルの継承を使用し、レンダリング時に子モデルごとに異なるデフォルト値が必要な場合、フィールドの初期値を指定する推奨される方法は何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"}