更新: これはチケット 14642として報告された Django の既存のバグだと思います
これは私を夢中にさせており、フォームコードが原因だと思っていましたが、モデルと管理者を使用して再作成できることに気付きました。ここで予想される動作が何であるかを知りたい:
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)
次の手順を実行します。
- admin でいくつかの ThingyItems を使用して新しい Thingy を作成し、保存します。
- 編集ページを開きます。
- 2 番目のブラウザー ウィンドウで同じものの編集ページを開きます。
- 最後の ThingyItem の [削除] ボタンをオンにして、2 番目のウィンドウに保存します。
- 最初のフォームに戻って保存します
これを行うと、次のようになります。
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 で報告する価値があると思います - そして私は今それをするつもりです - しかし、ここで誰かがこれを経験したことがあるかどうか疑問に思っていました。フォームによって想定されるこれらの前提条件がまだ有効かどうかをテストする簡単な方法はありますか? ビューまたはフォーム コードでそれを行う必要がありますか?