0

関連するモデルの3つのフォームセットをループしようとしていますが、「リストインデックスが範囲外です」というエラーで終了し続けます。しかし、それは非常に奇妙な場所でそれを行います。
たとえば、次のコードセグメントでは、num1が2、num2が4、num3が3の場合、外側のforループを1回正しくループし、外側のループの2回目の反復でのみ反復します。最初に内側のforループを2回実行してから、終了します。

num1 = Model1.objects.all().length()
num2 = Model2.objects.all().length()
num3 = numFromDatabase
FormSet1 = modelformset_factory(Model1, extra=num1, max_num=num1)
FormSet2 = modelformset_factory(Model2, extra=(num1*num2), max_num=(num1*num2))
FormSet2 = modelformset_factory(Model3, extra=(num1*num3), max_num=(num1*num3))
context = RequestContext(request)
if request.method == "POST":
    forms1 = FormSet1(request.POST)
    forms2 = FormSet2(request.POST)
    forms3 = FormSet3(request.POST)
    if forms1.is_valid() and forms2.is_valid() and forms3.is_valid():
        counter = 0
        objects1 = forms1.save(commit=False)
        for object1 in objects1:
            object1.attrib = stuffFromDatabase
            object1.save()
            for i, object4 in enumerate(Model4.objects.all()):
                ***object2 = forms2.__getitem__(counter * num2 + i).save(commit=False)***
                object2.attrib = stuffFromDatabase
                object2.related1 = object1
                object2.related4 = object4
                object2.save()
            for i in range(num3):
                object3 = forms3.__getitem__(counter * num3 + i).save(commit=False)
                object3.attrib = i
                object3.related1 = object1
                object3.save()
            counter += 1
        return HttpResponseRedirect('')
else:
        forms1 = FormSet1()
        forms2 = FormSet2()
        forms3 = FormSet3()
    return render_to_response('path/to/page.html', {'forms1': forms1, 'forms2': forms2, 'forms3': forms3}, context_instance=context)

私はそれに悪い数字を渡しているかどうかを理解しようとしましたが、私が言えることから私はそうではありません。ページ上に正しい数のフォームが表示されるため、何が原因で停止するのか本当にわかりません。(上記の数値を再度使用すると、forms1は2フォームの長さ、forms2は8フォームの長さ、forms3は6フォームの長さです。)ご

協力いただければ幸いです。ありがとうございました。

編集:これがトレースバックです。また、最初の内側のforループのすぐ内側で途切れる線をマークしました。

File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/path/to/views.py" in hardwaremktg
  263.                  object2 = forms2.__getitem__(counter * num2 + i).save(commit=False)
File "/Library/Python/2.7/site-packages/django/forms/formsets.py" in __getitem__
  61.         return self.forms[index]

Exception Type: IndexError at /my/view/
Exception Value: list index out of range
4

2 に答える 2

0

わかりました。フォームセットにプレフィックスを付けていないため、POST データに重複したフィールドが含まれていることがわかりました。変更された行は次のとおりです。

...
forms1 = FormSet1(request.POST, prefix='prefix1')
forms2 = FormSet2(request.POST, prefix='prefix2')
forms3 = FormSet3(request.POST, prefix='prefix3)
...
forms1 = FormSet1(prefix='prefix1')
forms2 = FormSet2(prefix='prefix2')
forms3 = FormSet3(prefix='prefix3')
于 2012-07-05T02:08:42.277 に答える
0

これは、各ループ内の値を考えれば明らかです。

データベースに 4 つの Model4 オブジェクトがあるとします。外側のループを初めて通過するときは、内側のループを 4 回繰り返します。の値はcounter * num2 + i、i=0->3、つまり 4、5、6、および 7 に対して (1 * 4 + i) になります。ここで、外側のループの最初の時間の終わりに、 をインクリメントcounterするので、計算は次のようになります。 now (2 * 4 + i) - つまり 8, 9, 10, 11: おっと、 には 8 つのフォームしかありませんforms2

(ループ内に print ステートメントを挿入するだけで、自分でそれを見つけることができたはずです。)

このロジックのいくつかについて、もう一度考え直さなければならないようです。そのバグがあるだけでなく、非常に非効率的でもあります。ループのたびに不必要に Model4 を照会するようなことをしています。__getitem__さらに、明示的なアクセスに関する私のコメントを参照してください。

于 2012-07-04T08:37:42.070 に答える