diff --git a/django/forms/models.py b/django/forms/models.py
index 626e727..d43595f 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -488,10 +488,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 3d75967..4dab266 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
@@ -804,6 +804,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
@@ -1003,7 +1008,7 @@ class AdminActionsTest(TestCase):
         }
         response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data)
         self.failUnlessEqual(response.status_code, 302)
-        
+
     def test_model_without_action(self):
         "Tests a ModelAdmin without any action"
         response = self.client.get('/test_admin/admin/admin_views/oldsubscriber/')
@@ -1012,7 +1017,7 @@ class AdminActionsTest(TestCase):
             '<input type="checkbox" class="action-select"' not in response.content,
             "Found an unexpected action toggle checkboxbox in response"
         )
-        
+
     def test_multiple_actions_form(self):
         """
         Test that actions come from the form whose submit button was pressed (#10618).
@@ -1076,7 +1081,7 @@ class AdminInlineFileUploadTest(TestCase):
 
     def setUp(self):
         self.client.login(username='super', password='secret')
-        
+
         # Set up test Picture and Gallery.
         # These must be set up here instead of in fixtures in order to allow Picture
         # to use a NamedTemporaryFile.
@@ -1095,7 +1100,7 @@ class AdminInlineFileUploadTest(TestCase):
 
     def test_inline_file_upload_edit_validation_error_post(self):
         """
-        Test that inline file uploads correctly display prior data (#10002). 
+        Test that inline file uploads correctly display prior data (#10002).
         """
         post_data = {
             "name": u"Test Gallery",
@@ -1112,4 +1117,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)
-
