diff --git a/django/forms/models.py b/django/forms/models.py
index 86eecee..910253c 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -560,10 +560,10 @@ class BaseModelFormSet(BaseFormSet):
         # data back. Generally, pk.editable should be false, but for some
         # reason, auto_created pk fields and AutoField's editable attribute is
         # True, so check for that as well.
-        def pk_is_editable(pk):
+        def pk_is_not_editable(pk):
             return ((not pk.editable) or (pk.auto_created or isinstance(pk, AutoField))
-                or (pk.rel and pk.rel.parent_link and pk_is_editable(pk.rel.to._meta.pk)))
-        if pk_is_editable(pk):
+                or (pk.rel and pk.rel.parent_link and pk_is_not_editable(pk.rel.to._meta.pk)))
+        if pk_is_not_editable(pk) or pk.name not in form.fields:
             try:
                 pk_value = self.get_queryset()[index].pk
             except IndexError:
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index 84a1688..dbadee4 100644
--- a/tests/regressiontests/admin_views/models.py
+++ b/tests/regressiontests/admin_views/models.py
@@ -325,6 +325,20 @@ class GalleryAdmin(admin.ModelAdmin):
 class PictureAdmin(admin.ModelAdmin):
     pass
 
+
+class Language(models.Model):
+    iso = models.CharField(max_length=5, primary_key=True)
+    name = models.CharField(max_length=50)
+    english_name = models.CharField(max_length=50)
+    shortlist = models.BooleanField(default=False)
+
+    class Meta:
+        ordering = ('iso',)
+
+class LanguageAdmin(admin.ModelAdmin):
+    list_display = ['iso', 'shortlist', 'english_name', 'name']
+    list_editable = ['shortlist']
+
 admin.site.register(Article, ArticleAdmin)
 admin.site.register(CustomArticle, CustomArticleAdmin)
 admin.site.register(Section, save_as=True, inlines=[ArticleInline])
@@ -343,6 +357,7 @@ admin.site.register(EmptyModel, EmptyModelAdmin)
 admin.site.register(Fabric, FabricAdmin)
 admin.site.register(Gallery, GalleryAdmin)
 admin.site.register(Picture, PictureAdmin)
+admin.site.register(Language, LanguageAdmin)
 
 # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
 # That way we cover all four cases:
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 960923b..a435003 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -16,7 +16,7 @@ from django.utils.html import escape
 from models import (Article, BarAccount, CustomArticle, EmptyModel,
                     ExternalSubscriber, FooAccount, Gallery,
                     ModelWithStringPrimaryKey, Person, Persona, Picture,
-                    Podcast, Section, Subscriber, Vodcast)
+                    Podcast, Section, Subscriber, Vodcast, Language)
 
 try:
     set
@@ -824,6 +824,11 @@ class AdminViewListEditable(TestCase):
         response = self.client.get('/test_admin/admin/admin_views/vodcast/')
         self.failUnlessEqual(response.status_code, 200)
 
+    def test_custom_pk(self):
+        Language.objects.create(iso='en', name='English', english_name='English')
+        response = self.client.get('/test_admin/admin/admin_views/language/')
+        self.failUnlessEqual(response.status_code, 200)
+
     def test_changelist_input_html(self):
         response = self.client.get('/test_admin/admin/admin_views/person/')
         # 2 inputs per object(the field and the hidden id field) = 6
@@ -1132,4 +1137,3 @@ class AdminInlineFileUploadTest(TestCase):
         }
         response = self.client.post('/test_admin/%s/admin_views/gallery/1/' % self.urlbit, post_data)
         self.failUnless(response._container[0].find("Currently:") > -1)
-
