#15574: IndexError: list index out of range caused by inline formsets ----------------------------+--------------------------- Reporter: poswald | Owner: nobody Status: new | Milestone: Component: Forms | Version: 1.3-beta Keywords: inline formset | Triage Stage: Unreviewed Has patch: 0 | ----------------------------+--------------------------- Note: I originally reported this as ticket #14642 but after discussion on the mailing list it has been decided that they are perhaps different issues. See http://groups.google.com/group/django- developers/browse_thread/thread/8c66461f1712dbb9
I was getting this error in my production system and I thought it was my forms. Turns out I could eliminate my forms as a source of the issue by using the admin. I've changed the summary to match. I reduced it down to this test case in Django 1.2.x: 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) }}} Now do the following: * Create a new Thingy with several ThingyItems? in the admin and save it. * Open the edit page. * Open the edit page for the same thingy in a second browser window. * Check the "Delete" button on the last ThingyItem? and save it in the second window. * Now go back to the first form and save it When I do this, I get: {{{ Traceback (most recent call last): File "/Users/poswald/Projects/django/tests/regressiontests/admin_inlines/tests.py", line 211, in test_concurrent_editing_views response = self.client.post(reverse(edit_url, args=[self.thing.pk]), data[1]) File "/Users/poswald/Projects/django/django/test/client.py", line 455, in post response = super(Client, self).post(path, data=data, content_type=content_type, **extra) File "/Users/poswald/Projects/django/django/test/client.py", line 256, in post return self.request(**r) File "/Users/poswald/Projects/django/django/core/handlers/base.py", line 111, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/Users/poswald/Projects/django/django/contrib/admin/options.py", line 308, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/Users/poswald/Projects/django/django/utils/decorators.py", line 93, in _wrapped_view response = view_func(request, *args, **kwargs) File "/Users/poswald/Projects/django/django/views/decorators/cache.py", line 79, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/Users/poswald/Projects/django/django/contrib/admin/sites.py", line 190, in inner return view(request, *args, **kwargs) File "/Users/poswald/Projects/django/django/utils/decorators.py", line 28, in _wrapper return bound_func(*args, **kwargs) File "/Users/poswald/Projects/django/django/utils/decorators.py", line 93, in _wrapped_view response = view_func(request, *args, **kwargs) File "/Users/poswald/Projects/django/django/utils/decorators.py", line 24, in bound_func return func(self, *args2, **kwargs2) File "/Users/poswald/Projects/django/django/db/transaction.py", line 217, in inner res = func(*args, **kwargs) File "/Users/poswald/Projects/django/django/contrib/admin/options.py", line 978, in change_view queryset=inline.queryset(request)) File "/Users/poswald/Projects/django/django/forms/models.py", line 680, in __init__ queryset=qs) File "/Users/poswald/Projects/django/django/forms/models.py", line 416, in __init__ super(BaseModelFormSet, self).__init__(**defaults) File "/Users/poswald/Projects/django/django/forms/formsets.py", line 47, in __init__ self._construct_forms() File "/Users/poswald/Projects/django/django/forms/formsets.py", line 108, in _construct_forms self.forms.append(self._construct_form(i)) File "/Users/poswald/Projects/django/django/forms/models.py", line 689, in _construct_form form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs) File "/Users/poswald/Projects/django/django/forms/models.py", line 440, in _construct_form kwargs['instance'] = self.get_queryset()[i] File "/Users/poswald/Projects/django/django/db/models/query.py", line 173, in __getitem__ return self._result_cache[k] IndexError: list index out of range }}} It seems that the inline formset code is a bit brittle. An error is thrown when the data submitted in the management form is not in agreement with the state of the database. I'd like to make an automated test case for this but I'm not sure how to do that sequence of steps in the test client. If anyone can shed some light onto what the formset code is *supposed* to do in this situation it would be useful. I imagine the options are the second form overrides the first or something like a form validation error is raised that indicates the form is stale. -- Ticket URL: <http://code.djangoproject.com/ticket/15574> Django <http://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.