diff --git a/django/forms/models.py b/django/forms/models.py
index 626e727..d43595f 100644
a
|
b
|
class BaseModelFormSet(BaseFormSet):
|
488 | 488 | # data back. Generally, pk.editable should be false, but for some |
489 | 489 | # reason, auto_created pk fields and AutoField's editable attribute is |
490 | 490 | # True, so check for that as well. |
491 | | def pk_is_editable(pk): |
| 491 | def pk_is_not_editable(pk): |
492 | 492 | return ((not pk.editable) or (pk.auto_created or isinstance(pk, AutoField)) |
493 | | or (pk.rel and pk.rel.parent_link and pk_is_editable(pk.rel.to._meta.pk))) |
494 | | if pk_is_editable(pk): |
| 493 | or (pk.rel and pk.rel.parent_link and pk_is_not_editable(pk.rel.to._meta.pk))) |
| 494 | if pk_is_not_editable(pk) or pk.name not in form.fields: |
495 | 495 | try: |
496 | 496 | pk_value = self.get_queryset()[index].pk |
497 | 497 | except IndexError: |
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index 84a1688..dbadee4 100644
a
|
b
|
class GalleryAdmin(admin.ModelAdmin):
|
325 | 325 | class PictureAdmin(admin.ModelAdmin): |
326 | 326 | pass |
327 | 327 | |
| 328 | |
| 329 | class Language(models.Model): |
| 330 | iso = models.CharField(max_length=5, primary_key=True) |
| 331 | name = models.CharField(max_length=50) |
| 332 | english_name = models.CharField(max_length=50) |
| 333 | shortlist = models.BooleanField(default=False) |
| 334 | |
| 335 | class Meta: |
| 336 | ordering = ('iso',) |
| 337 | |
| 338 | class LanguageAdmin(admin.ModelAdmin): |
| 339 | list_display = ['iso', 'shortlist', 'english_name', 'name'] |
| 340 | list_editable = ['shortlist'] |
| 341 | |
328 | 342 | admin.site.register(Article, ArticleAdmin) |
329 | 343 | admin.site.register(CustomArticle, CustomArticleAdmin) |
330 | 344 | admin.site.register(Section, save_as=True, inlines=[ArticleInline]) |
… |
… |
admin.site.register(EmptyModel, EmptyModelAdmin)
|
343 | 357 | admin.site.register(Fabric, FabricAdmin) |
344 | 358 | admin.site.register(Gallery, GalleryAdmin) |
345 | 359 | admin.site.register(Picture, PictureAdmin) |
| 360 | admin.site.register(Language, LanguageAdmin) |
346 | 361 | |
347 | 362 | # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. |
348 | 363 | # 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
|
b
|
from django.utils.html import escape
|
16 | 16 | from models import (Article, BarAccount, CustomArticle, EmptyModel, |
17 | 17 | ExternalSubscriber, FooAccount, Gallery, |
18 | 18 | ModelWithStringPrimaryKey, Person, Persona, Picture, |
19 | | Podcast, Section, Subscriber, Vodcast) |
| 19 | Podcast, Section, Subscriber, Vodcast, Language) |
20 | 20 | |
21 | 21 | try: |
22 | 22 | set |
… |
… |
class AdminViewListEditable(TestCase):
|
804 | 804 | response = self.client.get('/test_admin/admin/admin_views/vodcast/') |
805 | 805 | self.failUnlessEqual(response.status_code, 200) |
806 | 806 | |
| 807 | def test_custom_pk(self): |
| 808 | Language.objects.create(iso='en', name='English', english_name='English') |
| 809 | response = self.client.get('/test_admin/admin/admin_views/language/') |
| 810 | self.failUnlessEqual(response.status_code, 200) |
| 811 | |
807 | 812 | def test_changelist_input_html(self): |
808 | 813 | response = self.client.get('/test_admin/admin/admin_views/person/') |
809 | 814 | # 2 inputs per object(the field and the hidden id field) = 6 |
… |
… |
class AdminActionsTest(TestCase):
|
1003 | 1008 | } |
1004 | 1009 | response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) |
1005 | 1010 | self.failUnlessEqual(response.status_code, 302) |
1006 | | |
| 1011 | |
1007 | 1012 | def test_model_without_action(self): |
1008 | 1013 | "Tests a ModelAdmin without any action" |
1009 | 1014 | response = self.client.get('/test_admin/admin/admin_views/oldsubscriber/') |
… |
… |
class AdminActionsTest(TestCase):
|
1012 | 1017 | '<input type="checkbox" class="action-select"' not in response.content, |
1013 | 1018 | "Found an unexpected action toggle checkboxbox in response" |
1014 | 1019 | ) |
1015 | | |
| 1020 | |
1016 | 1021 | def test_multiple_actions_form(self): |
1017 | 1022 | """ |
1018 | 1023 | Test that actions come from the form whose submit button was pressed (#10618). |
… |
… |
class AdminInlineFileUploadTest(TestCase):
|
1076 | 1081 | |
1077 | 1082 | def setUp(self): |
1078 | 1083 | self.client.login(username='super', password='secret') |
1079 | | |
| 1084 | |
1080 | 1085 | # Set up test Picture and Gallery. |
1081 | 1086 | # These must be set up here instead of in fixtures in order to allow Picture |
1082 | 1087 | # to use a NamedTemporaryFile. |
… |
… |
class AdminInlineFileUploadTest(TestCase):
|
1095 | 1100 | |
1096 | 1101 | def test_inline_file_upload_edit_validation_error_post(self): |
1097 | 1102 | """ |
1098 | | Test that inline file uploads correctly display prior data (#10002). |
| 1103 | Test that inline file uploads correctly display prior data (#10002). |
1099 | 1104 | """ |
1100 | 1105 | post_data = { |
1101 | 1106 | "name": u"Test Gallery", |
… |
… |
class AdminInlineFileUploadTest(TestCase):
|
1112 | 1117 | } |
1113 | 1118 | response = self.client.post('/test_admin/%s/admin_views/gallery/1/' % self.urlbit, post_data) |
1114 | 1119 | self.failUnless(response._container[0].find("Currently:") > -1) |
1115 | | |