次のような 2 つのモデルがあります。
class RouteBase(models.Model):
base = models.ForeignKey("Base")
route = models.ForeignKey("Route")
sequence = models.IntegerField()
class Route(models.Model):
bases = models.ManyToManyField("Base", through="RouteBase", blank=True)
description = models.TextField(blank=True)
#and a few other attributes omitted for brevity
...次に、次のようなモデルフォーム:
class RouteBaseForm(ModelForm):
base = forms.ModelChoiceField(queryset=Base.objects.all(), widget=forms.TextInput)
sequence = forms.IntegerField(widget=forms.HiddenInput)
class Meta:
model = RouteBase
ご覧のとおり、シーケンス ウィジェットは非表示になっています。これは、このフィールドが django によって自動的に処理されるようにするためです。ユーザーは、テキスト ボックスから Base を入力するだけで済みます。シーケンスは、テキスト ボックスの順序によって推測されます。
ルート内のすべてのベースを作成/編集するために、このフォームを使用してフォームセットを作成しました。
RouteBaseFormset = inlineformset_factory(Route, RouteBase, form=RouteBaseForm, extra=5, )
このフォームセットが作成されるとき、シーケンス フィールドは空です。フォームセットを保存する前に値を入力する必要があります (そうしないと検証されません)。私はこれについて約4つの方法を考えることができます
- フォームセットをテンプレートに送信する直前に、次のコードを実行します。
i=1 formset.forms のフォームの場合: form.fields["sequence"].initial = i 私は += 1
1 つの問題を除いて、これは正常に動作します。フォームセットが保存のためにビューに送信されると、フォームセットで作成された 5 つの追加フィールドすべてにシーケンス値が入力されます。これは、ユーザーがルートに 2 つまたは 3 つの塩基のみを追加したい場合に問題を引き起こします。そのフォームの必須フィールド「ベース」が空であるため、検証エラーがポップアップ表示されます。フォームセットが POST された後、ベースが存在するかどうかを確認するコードを少し実行できます。存在しない場合はシーケンスを削除しますが、それを行う場合は...
フォームセットが POST されたときに、ベースが入力されているかどうかを確認するコードを少し実行します。入力されている場合はシーケンスを追加し、そうでない場合はそのフィールドを空白のままにします。そうすれば、フォームセットにアクセスしようとすると
.save()
、空の値により、その特定のフォームがデータベースに入れられないことが保証されます。.save(commit=False)
唯一の問題は、フォームセットが検証されないため、実行するまでフォームに対して何もできないことです。しかし、私はできました...変数をコピーしてシーケンスを手動で設定することにより、シーケンス値を追加します
request.POST
が、それは非常にハックに思えます。blank=True
フィールドの 1 つから削除することもできRouteBase
ますが、実際にはそうしたくありません。
それで、私はここで何をすべきですか?