用户同时编辑时,Django 内联表单集抛出 IndexError

Posted

技术标签:

【中文标题】用户同时编辑时,Django 内联表单集抛出 IndexError【英文标题】:Django inline formset throws IndexError when users are concurrently editing 【发布时间】:2011-07-10 05:17:15 【问题描述】:

更新:我现在认为这是 Django 中的一个现有错误,报告为 Ticket 14642

这让我发疯了,我认为这是由于我的表单代码,但我现在意识到我可以使用我的模型和管理员重新创建它。我想知道这里的预期行为是什么:

models.py:

class Thingy(models.Model):
    description = models.CharField(max_length=256)

class ThingyItem(models.Model):
    thingy = models.ForeignKey(Thingy)
    description = models.CharField(max_length=256)

admin.py:

class ThingyItemInline(admin.TabularInline):
    model = ThingyItem
    extra = 0

class ThingyAdmin(admin.ModelAdmin):
    inlines = [ThingyItemInline,]

admin.site.register(Thingy, ThingyAdmin)
admin.site.register(ThingyItem)

现在执行以下操作:

在管理员中创建一个包含多个 ThingyItem 的新 Thingy 并保存。 打开编辑页面。 在第二个浏览器窗口中打开同一事物的编辑页面。 选中最后一个 ThingyItem 上的“删除”按钮并将其保存在第二个窗口中。 现在返回第一个表单并保存

当我这样做时,我得到:

Traceback:
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/contrib/admin/options.py" in wrapper
  265.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapped_view
  76.                     response = view_func(request, *args, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  78.         response = view_func(request, *args, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/contrib/admin/sites.py" in inner
  190.             return view(request, *args, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapper
  21.             return decorator(bound_func)(*args, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapped_view
  76.                     response = view_func(request, *args, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/utils/decorators.py" in bound_func
  17.                 return func(self, *args2, **kwargs2)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/db/transaction.py" in _commit_on_success
  299.                     res = func(*args, **kw)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/contrib/admin/options.py" in change_view
  916.                                   queryset=inline.queryset(request))
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/forms/models.py" in __init__
  701.                                                 queryset=qs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/forms/models.py" in __init__
  427.         super(BaseModelFormSet, self).__init__(**defaults)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/forms/formsets.py" in __init__
  47.         self._construct_forms()
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/forms/formsets.py" in _construct_forms
  98.             self.forms.append(self._construct_form(i))
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/forms/models.py" in _construct_form
  714.         form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/forms/models.py" in _construct_form
  451.             kwargs['instance'] = self.get_queryset()[i]
File "/Users/poswald/.virtualenvs/hats/lib/python2.6/site-packages/django/db/models/query.py" in __getitem__
  171.             return self._result_cache[k]

Exception Type: IndexError at /admin/exampletest/thingy/1/
Exception Value: list index out of range

我不会真正关心管理员中的这一点,除非它发生在我们的生产服务器上使用我自己的表单的代码中。内联表单集代码似乎很脆弱。当它确实应该检查这些假设是否仍然有效时,它会信任与管理表单一起发送的数据。

现在,我认为这值得在 Django Trac 中报告 - 我计划现在就这样做 - 但是我想知道这里是否有人遇到过这种情况,如果有,你是如何解决的?有没有一种简单的方法来测试表单假设的这些先决条件是否仍然有效?我应该在我的视图或表单代码中这样做吗?

【问题讨论】:

【参考方案1】:

对于其他人来说,这似乎是 Django 中的一个错误。我在这里打开了一个问题:http://code.djangoproject.com/ticket/15574

【讨论】:

以上是关于用户同时编辑时,Django 内联表单集抛出 IndexError的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django-extra-views 将请求传递到内联表单集中

来自内部连接查询的更新集抛出错误 [重复]

Django 的内联表单

django 内联表单集的单选按钮

如何在 Django 的表单中拥有嵌套的内联表单集?

如何在管理界面中内联编辑 django 用户配置文件?