Django视图“列表索引超出范围”,循环以奇数p结束

2024-07-03 07:26:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图循环3个相关模型的表单集,但它总是以“列表索引超出范围”错误终止。然而,它却在一个非常奇怪的地方做到了。
例如,在下面的代码段中,如果num1为2,num2为4,num3为3,它将正确地循环外部For循环一次,然后在第二次外循环迭代时,它将只在第一个内部For循环上迭代两次,然后终止。在

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个forms long,forms2为8个forms long,forms3为6个forms long。)

任何帮助都将不胜感激。谢谢您。在

编辑:这是回溯。我还标记了中断的行,就在第一个inner for循环内。在

^{pr2}$

Tags: forrequestsavecounterpostobject1num2num1
2条回答

当您考虑每个循环中的值时,这应该很清楚。在

假设数据库中有4个Model4对象。第一次通过外部循环时,它将迭代内部循环4次。如果i=0->;3,即4、5、6和7,counter * num2 + i的值将为(1*4+i)。现在,在第一次通过外循环结束时,您将counter递增,因此计算现在是(2*4+i)-即8,9,10,11:oops,forms2中只有8个形式。在

(请注意,只要在循环中插入print语句,您就可以发现这一点。)

看来你应该再想想这个逻辑。不仅存在这个bug,而且效率也非常低:每次都不必要地通过循环查询Model4。另外,请参阅我关于显式访问__getitem__的评论。在

好吧,我想好了。原来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')

相关问题 更多 >