web-dev-qa-db-ja.com

保存する前にModelFormオブジェクトにデータを追加します

次のようなフォームがあるとします。

forms.py

class CreateASomethingForm(ModelForm):
    class Meta:
        model = Something
        fields = ['field2', 'field3', 'field4']

フォームにこれらの3つのフィールドが必要です。ただし、私のSomethingclassにもfield1があります。私の質問は、ModelFormを使用してデータを収集していない場合、field1にデータを追加するにはどうすればよいですか。私はこのようなことをやろうとしましたが、うまくいかず、これを解決する適切な方法がわかりません:

views.py

def create_something_view(request):
    if (request.method == 'POST'):
        # Create an object of the form based on POST data
        obj = CreateASomething(request.POST)
        # ** Add data into the blank field1 ** (Throwing an error)
        obj['field1'] = request.user
        # ... validate, save, then redirect 

私が受け取るエラーは:

TypeError: 'CreateAClassForm' object does not support item assignment

Djangoでは、保存する前にModelFormオブジェクトにデータを割り当てる適切な方法は何ですか?

29
Joker
form = CreateASomething(request.POST)
if form.is_valid():
    obj = form.save(commit=False)
    obj.field1 = request.user
    obj.save()
53
Daniel Roseman

場合によっては、フィールドが必要になることがあります。これは、form.is_valid()を過ぎてフィールドを作成できないことを意味します。その場合、すべてのフィールドを含むdictオブジェクトをフォームに渡すことができます。

   if request.method == 'POST':
       data = {
        'fields1': request.user,
        'fields2': additional_data,
       }
       form = CreateASomethingForm(data)

    if form.is_valid():
        form.commit(save)
6
eosimosu

これは、特にテスト中に使用されるデータを追加するためのより適切な方法です。

まず、model_to_dict関数を使用して既存のエントリを辞書に変換します

from Django.forms.models import model_to_dict

...

valid_data = model_to_dict(entry)

次に、新しいデータをこの辞書に追加します

valid_data['finish_time'] = '18:44'

これはフォームで値を設定するよりもうまく機能します

update_form.finish_time = '18:44'

有効なデータとインスタンスでフォームを作成します

update_form = UserEntryForm(valid_data, instance=entry)

必要なアサーションを実行します。

self.assertTrue(update_form.is_valid())
entry = update_form.save()
self.assertEqual(
    entry.status,
    1
)
1
surfer190