﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15574	IndexError: list index out of range caused by inline formsets	Paul Oswald	nobody	"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.

"	Bug	new	Forms	dev	Normal		inline formset	Patrick Kranzlmueller Paul Oswald Alan Justino da Silva django@… nik@… joseph@… cmawebsite@… milos.urbanek@… carsten.fuchs@…	Accepted	0	0	0	0	0	0
