Django:删除对象导致IndexError

时间:2014-04-15 16:55:20

标签: python ajax django

我有点困惑,我需要一些帮助。

我正在使用ModelFormset显示我的对象,然后我使用Ajax动态删除它们,然后使用Ajax调用再次保存所有对象。一切都是动态的,页面不会随时重新加载。

问题是,当Django尝试使用Ajax保存整个formset后,删除了一个或两个对象,它会查找已删除的对象并引发IndexError: list index out of range,因为该对象不再是查询集了。

这就是我显示和保存表单集的方式(简化版本 - 我认为这是错误的来源):

def App(request, slug):
    TopicFormSet = modelformset_factory(Topic, form=TopicForm, extra=0, fields=('name',), can_delete=True)
    SummaryFormSet = modelformset_factory(Summary, form=SummaryForm, extra=0, fields=('content',), can_delete=True)
    tquery = user.topic_set.all().order_by('date')
    squery = user.summary_set.all().order_by('date')
    # saving formsets:
    if request.method == 'POST' and request.is_ajax():
        # the following two lines is where the error comes from:
        t_formset = TopicFormSet(request.POST) # formset instance
        s_formset = SummaryFormSet(request.POST) # formset instance
        s_formset.save()
        t_formset.save()
    return render (blah...)

这是我删除对象的方式(这是一个不同的视图):

def Remove_topic(request, slug, id):
    topic = Topic.objects.get(pk=id)
    summary = Summary.objects.get(topic = topic) # foreign key relatonship

    topic.delete()
    summary.delete()

    # Ajax stuff....
    if request.is_ajax():
        return HttpResponse('blah..')

我在实例化queryset = tqueryqueryset = squery时尝试放置t_formsets_formset,但它没有帮助。我该怎么办 ?我正在使用Postgres数据库,如果它有用。

错误:

> File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 115, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/decorators.py", line 25, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/eimantas/Desktop/Projects/Lynx/lynx/views.py", line 122, in App
    t_formset = TopicFormSet(request.POST, queryset = tquery)
  File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 441, in __init__
    super(BaseModelFormSet, self).__init__(**defaults)
  File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py", line 56, in __init__
    self._construct_forms()
  File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py", line 124, in _construct_forms
    self.forms.append(self._construct_form(i))
  File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 468, in _construct_form
    kwargs['instance'] = self.get_queryset()[i]
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 198, in __getitem__
    return self._result_cache[k]
IndexError: list index out of range

3 个答案:

答案 0 :(得分:0)

这可能是已删除摘要对象的级联删除的情况:

  

删除ForeignKey引用的对象时,Django by   default模拟SQL约束ON DELETE CASCADE的行为   并删除包含ForeignKey的对象。

https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.on_delete

答案 1 :(得分:0)

它与第二个视图和Ajax调用无关。我认为你搞砸了management form's fields。与initial_form_counttotal_form_count或类似内容类似。

另一个重点。在检查formset是否有效之前,请不要保存它:

t_formset = TopicFormSet(request.POST)
if t_formset.is_valid():
    t_formset.save()

答案 2 :(得分:0)

在G +组中,我被告知技术上可以重置或重新加载"查询集,但在各个层面维护"非常困难。并且可能没有任何好处。我被建议使用迭代并检查在保存formset表单时是否已成功保存每个对象(我必须覆盖form = TopicForm&{39}和form = SummaryForm' s {{1方法。)

我决定根本不使用formset,但是为了单独列出和保存每个对象,对我和我的应用程序的业务逻辑会更好。