Index: django/contrib/admin/options.py
===================================================================
--- django/contrib/admin/options.py	(revision 9834)
+++ django/contrib/admin/options.py	(working copy)
@@ -522,10 +522,11 @@
             else:
                 form_validated = False
                 new_object = self.model()
-            for FormSet in self.get_formsets(request):
+            for idx, FormSet in enumerate(self.get_formsets(request)):
                 formset = FormSet(data=request.POST, files=request.FILES,
                                   instance=new_object,
-                                  save_as_new=request.POST.has_key("_saveasnew"))
+                                  save_as_new=request.POST.has_key("_saveasnew"),
+                                  prefix="form-%s" % idx)
                 formsets.append(formset)
             if all_valid(formsets) and form_validated:
                 self.save_model(request, new_object, form, change=False)
@@ -547,8 +548,8 @@
                 if isinstance(f, models.ManyToManyField):
                     initial[k] = initial[k].split(",")
             form = ModelForm(initial=initial)
-            for FormSet in self.get_formsets(request):
-                formset = FormSet(instance=self.model())
+            for idx, FormSet in enumerate(self.get_formsets(request)):
+                formset = FormSet(instance=self.model(), prefix="form-%s" % idx)
                 formsets.append(formset)
         
         adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
@@ -608,9 +609,9 @@
             else:
                 form_validated = False
                 new_object = obj
-            for FormSet in self.get_formsets(request, new_object):
+            for idx, FormSet in enumerate(self.get_formsets(request, new_object)):
                 formset = FormSet(request.POST, request.FILES,
-                                  instance=new_object)
+                                  instance=new_object, prefix="form-%s" % idx)
                 formsets.append(formset)
             
             if all_valid(formsets) and form_validated:
@@ -625,8 +626,8 @@
         
         else:
             form = ModelForm(instance=obj)
-            for FormSet in self.get_formsets(request, obj):
-                formset = FormSet(instance=obj)
+            for idx, FormSet in enumerate(self.get_formsets(request, obj)):
+                formset = FormSet(instance=obj, prefix="form-%s" % idx)
                 formsets.append(formset)
         
         adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
Index: django/contrib/contenttypes/generic.py
===================================================================
--- django/contrib/contenttypes/generic.py	(revision 9834)
+++ django/contrib/contenttypes/generic.py	(working copy)
@@ -291,7 +291,8 @@
     ct_field_name = "content_type"
     ct_fk_field_name = "object_id"
 
-    def __init__(self, data=None, files=None, instance=None, save_as_new=None):
+    def __init__(self, data=None, files=None, instance=None, prefix=None, 
+                    save_as_new=None):
         opts = self.model._meta
         self.instance = instance
         self.rel_name = '-'.join((
@@ -300,7 +301,7 @@
         ))
         super(BaseGenericInlineFormSet, self).__init__(
             queryset=self.get_queryset(), data=data, files=files,
-            prefix=self.rel_name
+            prefix=prefix or self.rel_name
         )
 
     def get_queryset(self):
Index: tests/regressiontests/admin_views/tests.py
===================================================================
--- tests/regressiontests/admin_views/tests.py	(revision 9834)
+++ tests/regressiontests/admin_views/tests.py	(working copy)
@@ -9,7 +9,7 @@
 from django.utils.html import escape
 
 # local test models
-from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey
+from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Persona, FooAccount, BarAccount
 
 class AdminViewBasicTest(TestCase):
     fixtures = ['admin-views-users.xml', 'admin-views-colors.xml']
@@ -63,8 +63,8 @@
         post_data = {
             "name": u"Another Section",
             # inline data
-            "article_set-TOTAL_FORMS": u"3",
-            "article_set-INITIAL_FORMS": u"0",
+            "form-0-TOTAL_FORMS": u"3",
+            "form-0-INITIAL_FORMS": u"0",
         }
         response = self.client.post('/test_admin/%s/admin_views/section/add/' % self.urlbit, post_data)
         self.failUnlessEqual(response.status_code, 302) # redirect somewhere
@@ -76,40 +76,40 @@
         post_data = {
             "name": u"Test section",
             # inline data
-            "article_set-TOTAL_FORMS": u"6",
-            "article_set-INITIAL_FORMS": u"3",
-            "article_set-0-id": u"1",
+            "form-0-TOTAL_FORMS": u"6",
+            "form-0-INITIAL_FORMS": u"3",
+            "form-0-0-id": u"1",
             # there is no title in database, give one here or formset
             # will fail.
-            "article_set-0-title": u"Norske bostaver æøå skaper problemer",
-            "article_set-0-content": u"&lt;p&gt;Middle content&lt;/p&gt;",
-            "article_set-0-date_0": u"2008-03-18",
-            "article_set-0-date_1": u"11:54:58",
-            "article_set-1-id": u"2",
-            "article_set-1-title": u"Need a title.",
-            "article_set-1-content": u"&lt;p&gt;Oldest content&lt;/p&gt;",
-            "article_set-1-date_0": u"2000-03-18",
-            "article_set-1-date_1": u"11:54:58",
-            "article_set-2-id": u"3",
-            "article_set-2-title": u"Need a title.",
-            "article_set-2-content": u"&lt;p&gt;Newest content&lt;/p&gt;",
-            "article_set-2-date_0": u"2009-03-18",
-            "article_set-2-date_1": u"11:54:58",
-            "article_set-3-id": u"",
-            "article_set-3-title": u"",
-            "article_set-3-content": u"",
-            "article_set-3-date_0": u"",
-            "article_set-3-date_1": u"",
-            "article_set-4-id": u"",
-            "article_set-4-title": u"",
-            "article_set-4-content": u"",
-            "article_set-4-date_0": u"",
-            "article_set-4-date_1": u"",
-            "article_set-5-id": u"",
-            "article_set-5-title": u"",
-            "article_set-5-content": u"",
-            "article_set-5-date_0": u"",
-            "article_set-5-date_1": u"",
+            "form-0-0-title": u"Norske bostaver æøå skaper problemer",
+            "form-0-0-content": u"&lt;p&gt;Middle content&lt;/p&gt;",
+            "form-0-0-date_0": u"2008-03-18",
+            "form-0-0-date_1": u"11:54:58",
+            "form-0-1-id": u"2",
+            "form-0-1-title": u"Need a title.",
+            "form-0-1-content": u"&lt;p&gt;Oldest content&lt;/p&gt;",
+            "form-0-1-date_0": u"2000-03-18",
+            "form-0-1-date_1": u"11:54:58",
+            "form-0-2-id": u"3",
+            "form-0-2-title": u"Need a title.",
+            "form-0-2-content": u"&lt;p&gt;Newest content&lt;/p&gt;",
+            "form-0-2-date_0": u"2009-03-18",
+            "form-0-2-date_1": u"11:54:58",
+            "form-0-3-id": u"",
+            "form-0-3-title": u"",
+            "form-0-3-content": u"",
+            "form-0-3-date_0": u"",
+            "form-0-3-date_1": u"",
+            "form-0-4-id": u"",
+            "form-0-4-title": u"",
+            "form-0-4-content": u"",
+            "form-0-4-date_0": u"",
+            "form-0-4-date_1": u"",
+            "form-0-5-id": u"",
+            "form-0-5-title": u"",
+            "form-0-5-content": u"",
+            "form-0-5-date_0": u"",
+            "form-0-5-date_1": u"",
         }
         response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, post_data)
         self.failUnlessEqual(response.status_code, 302) # redirect somewhere
@@ -687,26 +687,26 @@
         post_data = {
             "name": u"Test lærdommer",
             # inline data
-            "chapter_set-TOTAL_FORMS": u"6",
-            "chapter_set-INITIAL_FORMS": u"3",
-            "chapter_set-0-id": u"1",
-            "chapter_set-0-title": u"Norske bostaver æøå skaper problemer",
-            "chapter_set-0-content": u"&lt;p&gt;Svært frustrerende med UnicodeDecodeError&lt;/p&gt;",
-            "chapter_set-1-id": u"2",
-            "chapter_set-1-title": u"Kjærlighet.",
-            "chapter_set-1-content": u"&lt;p&gt;La kjærligheten til de lidende seire.&lt;/p&gt;",
-            "chapter_set-2-id": u"3",
-            "chapter_set-2-title": u"Need a title.",
-            "chapter_set-2-content": u"&lt;p&gt;Newest content&lt;/p&gt;",
-            "chapter_set-3-id": u"",
-            "chapter_set-3-title": u"",
-            "chapter_set-3-content": u"",
-            "chapter_set-4-id": u"",
-            "chapter_set-4-title": u"",
-            "chapter_set-4-content": u"",
-            "chapter_set-5-id": u"",
-            "chapter_set-5-title": u"",
-            "chapter_set-5-content": u"",
+            "form-0-TOTAL_FORMS": u"6",
+            "form-0-INITIAL_FORMS": u"3",
+            "form-0-0-id": u"1",
+            "form-0-0-title": u"Norske bostaver æøå skaper problemer",
+            "form-0-0-content": u"&lt;p&gt;Svært frustrerende med UnicodeDecodeError&lt;/p&gt;",
+            "form-0-1-id": u"2",
+            "form-0-1-title": u"Kjærlighet.",
+            "form-0-1-content": u"&lt;p&gt;La kjærligheten til de lidende seire.&lt;/p&gt;",
+            "form-0-2-id": u"3",
+            "form-0-2-title": u"Need a title.",
+            "form-0-2-content": u"&lt;p&gt;Newest content&lt;/p&gt;",
+            "form-0-3-id": u"",
+            "form-0-3-title": u"",
+            "form-0-3-content": u"",
+            "form-0-4-id": u"",
+            "form-0-4-title": u"",
+            "form-0-4-content": u"",
+            "form-0-5-id": u"",
+            "form-0-5-title": u"",
+            "form-0-5-content": u"",
         }
 
         response = self.client.post('/test_admin/admin/admin_views/book/1/', post_data)
@@ -721,3 +721,38 @@
         self.failUnlessEqual(response.status_code, 200)
         response = self.client.post('/test_admin/admin/admin_views/book/1/delete/', delete_dict)
         self.assertRedirects(response, '/test_admin/admin/admin_views/book/')
+
+class AdminInheritedInlinesTest(TestCase):
+    fixtures = ['admin-views-users.xml',]
+    
+    def setUp(self):
+        self.client.login(username='super', password='secret')
+    
+    def tearDown(self):
+        self.client.logout()
+    
+    def testInlineInsert(self):
+        "Ensure that inline models which inherit from a common parent are correctly handled by admin."
+        
+        foo_user = u"foo username"
+        bar_user = u"bar username"
+        
+        post_data = {
+            "name": u"Test Name",
+            # inline data
+            "form-0-TOTAL_FORMS": u"1",
+            "form-0-INITIAL_FORMS": u"0",
+            "form-0-0-username": foo_user,
+            "form-1-TOTAL_FORMS": u"1",
+            "form-1-INITIAL_FORMS": u"0",
+            "form-1-0-username": bar_user,
+        }
+        
+        response = self.client.post('/test_admin/admin/admin_views/persona/add/', post_data)
+        self.failUnlessEqual(response.status_code, 302) # redirect somewhere
+        self.failUnlessEqual(Persona.objects.count(), 1)
+        self.failUnlessEqual(FooAccount.objects.count(), 1)
+        self.failUnlessEqual(BarAccount.objects.count(), 1)
+        self.failUnlessEqual(FooAccount.objects.all()[0].username, foo_user)
+        self.failUnlessEqual(BarAccount.objects.all()[0].username, bar_user)
+        self.failUnlessEqual(Persona.objects.all()[0].accounts.count(), 2)
\ No newline at end of file
Index: tests/regressiontests/admin_views/models.py
===================================================================
--- tests/regressiontests/admin_views/models.py	(revision 9834)
+++ tests/regressiontests/admin_views/models.py	(working copy)
@@ -134,12 +134,54 @@
 class ThingAdmin(admin.ModelAdmin):
     list_filter = ('color',)
 
+class Persona(models.Model):
+    """
+    A simple persona associated with accounts, to test inlining of related
+    accounts which inherit from a common accounts class.
+    """
+    name = models.CharField(blank=False,  max_length=80)
+    def __unicode__(self):
+        return self.name
+
+class Account(models.Model):
+    """
+    A simple, generic account encapsulating the information shared by all
+    types of accounts.
+    """
+    username = models.CharField(blank=False,  max_length=80)
+    persona = models.ForeignKey(Persona, related_name="accounts")
+    servicename = u'generic service'
+    
+    def __unicode__(self):
+        return "%s: %s" % (self.servicename, self.username)
+
+class FooAccount(Account):
+    """A service-specific account of type Foo."""
+    servicename = u'foo'
+
+class BarAccount(Account):
+    """A service-specific account of type Bar."""
+    servicename = u'bar'
+
+class FooAccountAdmin(admin.StackedInline):
+    model = FooAccount
+
+class BarAccountAdmin(admin.StackedInline):
+    model = BarAccount
+
+class PersonaAdmin(admin.ModelAdmin):
+    inlines = (
+        FooAccountAdmin,
+        BarAccountAdmin
+    )
+
 admin.site.register(Article, ArticleAdmin)
 admin.site.register(CustomArticle, CustomArticleAdmin)
 admin.site.register(Section, inlines=[ArticleInline])
 admin.site.register(ModelWithStringPrimaryKey)
 admin.site.register(Color)
 admin.site.register(Thing, ThingAdmin)
+admin.site.register(Persona, PersonaAdmin)
 
 # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
 # That way we cover all four cases:
@@ -153,3 +195,5 @@
 admin.site.register(Book, inlines=[ChapterInline])
 admin.site.register(Promo)
 admin.site.register(ChapterXtra1)
+
+
Index: tests/regressiontests/generic_inline_admin/tests.py
===================================================================
--- tests/regressiontests/generic_inline_admin/tests.py	(revision 9834)
+++ tests/regressiontests/generic_inline_admin/tests.py	(working copy)
@@ -51,8 +51,8 @@
         post_data = {
             "name": u"This Week in Django",
             # inline data
-            "generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"1",
-            "generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"0",
+            "form-0-TOTAL_FORMS": u"1",
+            "form-0-INITIAL_FORMS": u"0",
         }
         response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/episode/add/', post_data)
         self.failUnlessEqual(response.status_code, 302) # redirect somewhere
@@ -64,12 +64,12 @@
         post_data = {
             "name": u"This Week in Django",
             # inline data
-            "generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"2",
-            "generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"1",
-            "generic_inline_admin-media-content_type-object_id-0-id": u"%d" % self.media_pk,
-            "generic_inline_admin-media-content_type-object_id-0-url": u"http://example.com/podcast.mp3",
-            "generic_inline_admin-media-content_type-object_id-1-id": u"",
-            "generic_inline_admin-media-content_type-object_id-1-url": u"",
+            "form-0-TOTAL_FORMS": u"2",
+            "form-0-INITIAL_FORMS": u"1",
+            "form-0-0-id": u"%d" % self.media_pk,
+            "form-0-0-url": u"http://example.com/podcast.mp3",
+            "form-0-1-id": u"",
+            "form-0-1-url": u"",
         }
         url = '/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk
         response = self.client.post(url, post_data)
