From e508bfd27f34fc753ae32cc1776251e2d7f36610 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Thu, 14 May 2009 02:23:53 +0000 Subject: [PATCH] Fixed #10992: fixed a bug saving inlines with custom primary key fields. Thanks, Zain. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10777 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/forms/models.py | 7 +- tests/regressiontests/admin_views/tests.py | 126 ++++++++++----------- 2 files changed, 69 insertions(+), 64 deletions(-) diff --git a/django/forms/models.py b/django/forms/models.py index 705ef10f17..351234a433 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -612,7 +612,12 @@ class BaseModelFormSet(BaseFormSet): for form in self.initial_forms: pk_name = self._pk_field.name raw_pk_value = form._raw_value(pk_name) - pk_value = form.fields[pk_name].clean(raw_pk_value).pk + + # clean() for different types of PK fields can sometimes return + # the model instance, and sometimes the PK. Handle either. + pk_value = form.fields[pk_name].clean(raw_pk_value) + pk_value = getattr(pk_value, 'pk', pk_value) + obj = existing_objects[pk_value] if self.can_delete: raw_delete_value = form._raw_value(DELETION_FIELD_NAME) diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 65a246cd77..4f2a503b4f 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -1326,69 +1326,69 @@ class AdminInlineTests(TestCase): self.failUnlessEqual(Grommet.objects.count(), 1) self.failUnlessEqual(Grommet.objects.all()[0].name, "Grommet 1 Updated") - # def test_char_pk_inline(self): - # "A model with a character PK can be saved as inlines. Regression for #10992" - # # First add a new inline - # self.post_data['doohickey_set-0-code'] = "DH1" - # self.post_data['doohickey_set-0-name'] = "Doohickey 1" - # response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # self.failUnlessEqual(response.status_code, 302) - # self.failUnlessEqual(DooHickey.objects.count(), 1) - # self.failUnlessEqual(DooHickey.objects.all()[0].name, "Doohickey 1") - # - # # Check that the PK link exists on the rendered form - # response = self.client.get('/test_admin/admin/admin_views/collector/1/') - # self.assertContains(response, 'name="doohickey_set-0-code"') - # - # # Now resave that inline - # self.post_data['doohickey_set-INITIAL_FORMS'] = "1" - # self.post_data['doohickey_set-0-code'] = "DH1" - # self.post_data['doohickey_set-0-name'] = "Doohickey 1" - # response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # self.failUnlessEqual(response.status_code, 302) - # self.failUnlessEqual(DooHickey.objects.count(), 1) - # self.failUnlessEqual(DooHickey.objects.all()[0].name, "Doohickey 1") - # - # # Now modify that inline - # self.post_data['doohickey_set-INITIAL_FORMS'] = "1" - # self.post_data['doohickey_set-0-code'] = "DH1" - # self.post_data['doohickey_set-0-name'] = "Doohickey 1 Updated" - # response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # self.failUnlessEqual(response.status_code, 302) - # self.failUnlessEqual(DooHickey.objects.count(), 1) - # self.failUnlessEqual(DooHickey.objects.all()[0].name, "Doohickey 1 Updated") - - # def test_integer_pk_inline(self): - # "A model with an integer PK can be saved as inlines. Regression for #10992" - # # First add a new inline - # self.post_data['whatsit_set-0-index'] = "42" - # self.post_data['whatsit_set-0-name'] = "Whatsit 1" - # response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # self.failUnlessEqual(response.status_code, 302) - # self.failUnlessEqual(Whatsit.objects.count(), 1) - # self.failUnlessEqual(Whatsit.objects.all()[0].name, "Whatsit 1") - # - # # Check that the PK link exists on the rendered form - # response = self.client.get('/test_admin/admin/admin_views/collector/1/') - # self.assertContains(response, 'name="whatsit_set-0-index"') - # - # # Now resave that inline - # self.post_data['whatsit_set-INITIAL_FORMS'] = "1" - # self.post_data['whatsit_set-0-index'] = "42" - # self.post_data['whatsit_set-0-name'] = "Whatsit 1" - # response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # self.failUnlessEqual(response.status_code, 302) - # self.failUnlessEqual(Whatsit.objects.count(), 1) - # self.failUnlessEqual(Whatsit.objects.all()[0].name, "Whatsit 1") - # - # # Now modify that inline - # self.post_data['whatsit_set-INITIAL_FORMS'] = "1" - # self.post_data['whatsit_set-0-index'] = "42" - # self.post_data['whatsit_set-0-name'] = "Whatsit 1 Updated" - # response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # self.failUnlessEqual(response.status_code, 302) - # self.failUnlessEqual(Whatsit.objects.count(), 1) - # self.failUnlessEqual(Whatsit.objects.all()[0].name, "Whatsit 1 Updated") + def test_char_pk_inline(self): + "A model with a character PK can be saved as inlines. Regression for #10992" + # First add a new inline + self.post_data['doohickey_set-0-code'] = "DH1" + self.post_data['doohickey_set-0-name'] = "Doohickey 1" + response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) + self.failUnlessEqual(response.status_code, 302) + self.failUnlessEqual(DooHickey.objects.count(), 1) + self.failUnlessEqual(DooHickey.objects.all()[0].name, "Doohickey 1") + + # Check that the PK link exists on the rendered form + response = self.client.get('/test_admin/admin/admin_views/collector/1/') + self.assertContains(response, 'name="doohickey_set-0-code"') + + # Now resave that inline + self.post_data['doohickey_set-INITIAL_FORMS'] = "1" + self.post_data['doohickey_set-0-code'] = "DH1" + self.post_data['doohickey_set-0-name'] = "Doohickey 1" + response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) + self.failUnlessEqual(response.status_code, 302) + self.failUnlessEqual(DooHickey.objects.count(), 1) + self.failUnlessEqual(DooHickey.objects.all()[0].name, "Doohickey 1") + + # Now modify that inline + self.post_data['doohickey_set-INITIAL_FORMS'] = "1" + self.post_data['doohickey_set-0-code'] = "DH1" + self.post_data['doohickey_set-0-name'] = "Doohickey 1 Updated" + response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) + self.failUnlessEqual(response.status_code, 302) + self.failUnlessEqual(DooHickey.objects.count(), 1) + self.failUnlessEqual(DooHickey.objects.all()[0].name, "Doohickey 1 Updated") + + def test_integer_pk_inline(self): + "A model with an integer PK can be saved as inlines. Regression for #10992" + # First add a new inline + self.post_data['whatsit_set-0-index'] = "42" + self.post_data['whatsit_set-0-name'] = "Whatsit 1" + response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) + self.failUnlessEqual(response.status_code, 302) + self.failUnlessEqual(Whatsit.objects.count(), 1) + self.failUnlessEqual(Whatsit.objects.all()[0].name, "Whatsit 1") + + # Check that the PK link exists on the rendered form + response = self.client.get('/test_admin/admin/admin_views/collector/1/') + self.assertContains(response, 'name="whatsit_set-0-index"') + + # Now resave that inline + self.post_data['whatsit_set-INITIAL_FORMS'] = "1" + self.post_data['whatsit_set-0-index'] = "42" + self.post_data['whatsit_set-0-name'] = "Whatsit 1" + response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) + self.failUnlessEqual(response.status_code, 302) + self.failUnlessEqual(Whatsit.objects.count(), 1) + self.failUnlessEqual(Whatsit.objects.all()[0].name, "Whatsit 1") + + # Now modify that inline + self.post_data['whatsit_set-INITIAL_FORMS'] = "1" + self.post_data['whatsit_set-0-index'] = "42" + self.post_data['whatsit_set-0-name'] = "Whatsit 1 Updated" + response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) + self.failUnlessEqual(response.status_code, 302) + self.failUnlessEqual(Whatsit.objects.count(), 1) + self.failUnlessEqual(Whatsit.objects.all()[0].name, "Whatsit 1 Updated") def test_inherited_inline(self): "An inherited model can be saved as inlines. Regression for #11042"