14

ModelForm にインスタンスが与えられた場合、initialそのインスタンスが空のモデル レコードであっても、指定した値を無視し、代わりにインスタンスの値に設定するようです。

インスタンスフォームを作成し、初期データを設定する方法はありますか?

関連するレコードを保存していて、作成時に ModelForm にインスタンスが指定されていない限り、正しく保存されないように見えるため、必要です。

これに対する答えは簡単だと確信しており、明らかな何かが欠けているだけです。

関連するコードは次のとおりです。

ビューで:

form = form_class(person=person, conference=conference, initial=initial, instance=registration)

ここで、form_class はRegistrationForm登録フォームにあります。

class RegisterForm(forms.ModelForm):
    ... fields here ...

    def __init__(self, *args, **kwargs):
        ... other code ...
        self.person = kwargs.pop('person')
        super(RegisterForm, self).__init__(*args, **kwargs)
        for key, in self.fields.keys():
            if hasattr(self.person, key):
                self.fields[k].initial = getattr(self.person, key)

次に、フィールドを呼び出すと、関連するフィールドは空です。

4

3 に答える 3

8

少しグーグルで調べた後、これを理解しました。

を呼び出す前に初期値を設定する必要がありますsuper

そのため、をループする代わりに、self.fields.keys()必要なフィールドのリストを入力してループする必要がありました。

class RegisterForm(forms.ModelForm):
    ... fields here ...
    initial_fields = ['first_name', 'last_name', ... ]

    def __init__(self, *args, **kwargs):
        ... other code ...
        self.person = kwargs.pop('person')
        for key in self.initial_fields:
            if hasattr(self.person, key):
                self.fields[k].initial = getattr(self.person, key)
        super(RegisterForm, self).__init__(*args, **kwargs)

self.fields@Dariaは、スーパーを呼び出す前に持っていないことを正しく指摘しています。私はこれがうまくいくと確信しています:

class RegisterForm(forms.ModelForm):
    ... fields here ...
    initial_fields = ['first_name', 'last_name', ... ]

    def __init__(self, *args, **kwargs):
        ... other code ...
        initial = kwargs.pop('initial', {})
        self.person = kwargs.pop('person')
        for key in self.initial_fields:
            if hasattr(self.person, key):
                initial[key] = initial.get(key) or getattr(self.person, key)
        kwargs['initial'] = initial
        super(RegisterForm, self).__init__(*args, **kwargs)

このバージョンでは、initial引数を使用して値を渡します。また、そのフィールドの初期値に既に値がある場合、それを上書きしないように記述されています。

于 2013-08-15T14:04:13.300 に答える
2

バインドされたフォームを探しているように思えます。完全にはわかりませんが、同様の問題の選択を解除しようとしています:

Django フォームは、この種のものを制御する 2 つの引数でインスタンス化できます。私が理解しているように:

form = MyForm(initial={...}, data={...}, ...)

initial は、クエリセットの設定と同様に、フィールドに可能な値を設定します。<em>data は、フォームの実際の (または選択された) 値を設定し、バインドされたフォームを作成します。多分それはあなたが望むものです。もう 1 つの興味深い点は、コンストラクターではなくファクトリ メソッドを検討することです。構文の方が自然だと思います。

class MyForm(forms.ModelForm):

    ...

    @staticmethod
    def makeBoundForm(user):
        myObjSet = MyObject.objects.filter(some_attr__user=user)
        if len(myObjSet) is not 0:
            data = {'myObject': myObjSet[0]}
        else:
            raise ValueError()
        initial = {'myObject': myObjSet}
        return MyForm(initial=initial, data=data)
于 2015-06-11T07:25:45.140 に答える
1

クラスを初期化するときに、追加の変数をクラスに渡すこともできます。渡す値は、初期データまたは POST データをオーバーライドできます。

class RegisterForm(forms.ModelForm):
    ... fields here ...

    def __init__(self, person, conference, *args, **kwargs):
        ... other code ...
        super(RegisterForm, self).__init__(*args, **kwargs)
        self.fields['person'] = person
        self.fields['conference'] = conference

form = RegisterForm(person, conference, initial=initial, instance=registration)
于 2015-01-20T15:43:29.330 に答える