0

我正在尝试遍历 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 个表单,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次。对于 i=0->3的值counter * num2 + i将是 (1 * 4 + i),即 4、5、6 和 7。现在,在第一次通过外循环结束时,您递增counter,因此计算为现在 (2 * 4 + i) - 即 8、9、10、11:哎呀,你只有 8 个表格forms2

(请注意,您可以通过在循环中简单地插入打印语句来发现自己。)

看来您应该重新考虑其中的一些逻辑。不仅存在该错误,而且效率也非常低:您每次都在不必要地通过循环查询 Model4。另外,请参阅我关于__getitem__显式访问的评论。

于 2012-07-04T08:37:42.070 回答