#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.

Reply via email to