3

次のような 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つの方法を考えることができます

  1. フォームセットをテンプレートに送信する直前に、次のコードを実行します。
    i=1
    formset.forms のフォームの場合:
        form.fields["sequence"].initial = i
        私は += 1

1 つの問題を除いて、これは正常に動作します。フォームセットが保存のためにビューに送信されると、フォームセットで作成された 5 つの追加フィールドすべてにシーケンス値が入力されます。これは、ユーザーがルートに 2 つまたは 3 つの塩基のみを追加したい場合に問題を引き起こします。そのフォームの必須フィールド「ベース」が空であるため、検証エラーがポップアップ表示されます。フォームセットが POST された後、ベースが存在するかどうかを確認するコードを少し実行できます。存在しない場合はシーケンスを削除しますが、それを行う場合は...

  1. フォームセットが POST されたときに、ベースが入力されているかどうかを確認するコードを少し実行します。入力されている場合はシーケンスを追加し、そうでない場合はそのフィールドを空白のままにします。そうすれば、フォームセットにアクセスしようとすると.save()、空の値により、その特定のフォームがデータベースに入れられないことが保証されます。.save(commit=False)唯一の問題は、フォームセットが検証されないため、実行するまでフォームに対して何もできないことです。しかし、私はできました...

  2. 変数をコピーしてシーケンスを手動で設定することにより、シーケンス値を追加しますrequest.POSTが、それは非常にハックに思えます。

  3. blank=Trueフィールドの 1 つから削除することもできRouteBaseますが、実際にはそうしたくありません。

それで、私はここで何をすべきですか?

4

2 に答える 2

-2
newPOST = request.POST.copy()
i=1
for index in range(0, int(request.POST["routebase_set-TOTAL_FORMS"])-1):
    if request.POST["routebase_set-" + str(index) + "-base"]:
        newPOST["routebase_set-" + str(index) + "-sequence"] = i
        i += 1
    else:
        newPOST["routebase_set-" + str(index) + "-sequence"] = ""

正直なところ、これはフォームの検証をいじるよりもうまくいくようです。思ったほどハッキーではありません...

于 2009-06-21T15:10:36.983 に答える