diff --git a/django/forms/models.py b/django/forms/models.py index 95fc41e77f..d40a1ee55e 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -470,7 +470,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. - if (not pk.editable) or (pk.auto_created or isinstance(pk, AutoField)): + def pk_is_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): try: pk_value = self.get_queryset()[index].pk except IndexError: diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py index d8cbe34b94..f30b2125e2 100644 --- a/tests/modeltests/model_formsets/models.py +++ b/tests/modeltests/model_formsets/models.py @@ -108,6 +108,10 @@ class Price(models.Model): class MexicanRestaurant(Restaurant): serves_tacos = models.BooleanField() +class ClassyMexicanRestaurant(MexicanRestaurant): + restaurant = models.OneToOneField(MexicanRestaurant, parent_link=True, primary_key=True) + tacos_are_yummy = models.BooleanField() + # models for testing unique_together validation when a fk is involved and # using inlineformset_factory. class Repository(models.Model): @@ -934,4 +938,9 @@ True >>> formset.get_queryset() [] +# a formset for a Model that has a custom primary key that still needs to be +# added to the formset automatically +>>> FormSet = modelformset_factory(ClassyMexicanRestaurant, fields=["tacos_are_yummy"]) +>>> sorted(FormSet().forms[0].fields.keys()) +['restaurant', 'tacos_are_yummy'] """} diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index 211851f7b7..84a1688f7e 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -269,6 +269,16 @@ class PodcastAdmin(admin.ModelAdmin): ordering = ('name',) +class Vodcast(Media): + media = models.OneToOneField(Media, primary_key=True, parent_link=True) + released = models.BooleanField(default=False) + +class VodcastAdmin(admin.ModelAdmin): + list_display = ('name', 'released') + list_editable = ('released',) + + ordering = ('name',) + class Parent(models.Model): name = models.CharField(max_length=128) @@ -327,6 +337,7 @@ admin.site.register(Subscriber, SubscriberAdmin) admin.site.register(ExternalSubscriber, ExternalSubscriberAdmin) admin.site.register(OldSubscriber, OldSubscriberAdmin) admin.site.register(Podcast, PodcastAdmin) +admin.site.register(Vodcast, VodcastAdmin) admin.site.register(Parent, ParentAdmin) admin.site.register(EmptyModel, EmptyModelAdmin) admin.site.register(Fabric, FabricAdmin) diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index f8c790ef08..3d75967444 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -2,8 +2,6 @@ import re import datetime -import os - from django.core.files import temp as tempfile from django.test import TestCase from django.contrib.auth.models import User, Permission @@ -18,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) + Podcast, Section, Subscriber, Vodcast) try: set @@ -801,6 +799,11 @@ class AdminViewListEditable(TestCase): response = self.client.get('/test_admin/admin/admin_views/podcast/') self.failUnlessEqual(response.status_code, 200) + def test_inheritance_2(self): + Vodcast.objects.create(name="This Week in Django", released=True) + response = self.client.get('/test_admin/admin/admin_views/vodcast/') + 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