diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index f2723a1..0ff0ff2 100644
a
|
b
|
class ManyToManyField(RelatedField, Field):
|
955 | 955 | # A ManyToManyField is not represented by a single column, |
956 | 956 | # so return None. |
957 | 957 | return None |
958 | | |
diff --git a/django/forms/models.py b/django/forms/models.py
index 010d3bf..fa77611 100644
a
|
b
|
class BaseModelFormSet(BaseFormSet):
|
469 | 469 | # data back. Generally, pk.editable should be false, but for some |
470 | 470 | # reason, auto_created pk fields and AutoField's editable attribute is |
471 | 471 | # True, so check for that as well. |
472 | | if (not pk.editable) or (pk.auto_created or isinstance(pk, AutoField)): |
| 472 | def pk_is_editable(pk): |
| 473 | return ((not pk.editable) or (pk.auto_created or isinstance(pk, AutoField)) |
| 474 | or (pk.rel and pk.rel.parent_link and pk_is_editable(pk.rel.to._meta.pk))) |
| 475 | if pk_is_editable(pk): |
473 | 476 | try: |
474 | 477 | pk_value = self.get_queryset()[index].pk |
475 | 478 | except IndexError: |
diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py
index d8cbe34..718c73a 100644
a
|
b
|
class CustomPrimaryKey(models.Model):
|
58 | 58 | class Place(models.Model): |
59 | 59 | name = models.CharField(max_length=50) |
60 | 60 | city = models.CharField(max_length=50) |
61 | | |
| 61 | |
62 | 62 | def __unicode__(self): |
63 | 63 | return self.name |
64 | 64 | |
… |
… |
class OwnerProfile(models.Model):
|
85 | 85 | |
86 | 86 | class Restaurant(Place): |
87 | 87 | serves_pizza = models.BooleanField() |
88 | | |
| 88 | |
89 | 89 | def __unicode__(self): |
90 | 90 | return self.name |
91 | 91 | |
… |
… |
class Price(models.Model):
|
108 | 108 | class MexicanRestaurant(Restaurant): |
109 | 109 | serves_tacos = models.BooleanField() |
110 | 110 | |
| 111 | class ClassyMexicanRestaurant(MexicanRestaurant): |
| 112 | restaurant = models.OneToOneField(MexicanRestaurant, parent_link=True, primary_key=True) |
| 113 | tacos_are_yummy = models.BooleanField() |
| 114 | |
111 | 115 | # models for testing unique_together validation when a fk is involved and |
112 | 116 | # using inlineformset_factory. |
113 | 117 | class Repository(models.Model): |
… |
… |
True
|
569 | 573 | ... print book.title |
570 | 574 | Les Fleurs du Mal |
571 | 575 | |
572 | | Test inline formsets where the inline-edited object uses multi-table inheritance, thus |
| 576 | Test inline formsets where the inline-edited object uses multi-table inheritance, thus |
573 | 577 | has a non AutoField yet auto-created primary key. |
574 | 578 | |
575 | 579 | >>> AuthorBooksFormSet3 = inlineformset_factory(Author, AlternateBook, can_delete=False, extra=1) |
… |
… |
True
|
736 | 740 | >>> formset.save() |
737 | 741 | [<OwnerProfile: Joe Perry is 55>] |
738 | 742 | |
739 | | # ForeignKey with unique=True should enforce max_num=1 |
| 743 | # ForeignKey with unique=True should enforce max_num=1 |
740 | 744 | |
741 | 745 | >>> FormSet = inlineformset_factory(Place, Location, can_delete=False) |
742 | 746 | >>> formset = FormSet(instance=place) |
… |
… |
True
|
934 | 938 | >>> formset.get_queryset() |
935 | 939 | [<Player: Bobby>] |
936 | 940 | |
| 941 | # a formset for a Model that has a custom primary key that still needs to be |
| 942 | # added to the formset automatically |
| 943 | >>> FormSet = modelformset_factory(ClassyMexicanRestaurant, fields=["tacos_are_yummy"]) |
| 944 | >>> sorted(FormSet().forms[0].fields.keys()) |
| 945 | ['restaurant', 'tacos_are_yummy'] |
937 | 946 | """} |
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index f1c24c2..906c271 100644
a
|
b
|
class PodcastAdmin(admin.ModelAdmin):
|
266 | 266 | |
267 | 267 | ordering = ('name',) |
268 | 268 | |
| 269 | class Vodcast(Media): |
| 270 | media = models.OneToOneField(Media, primary_key=True, parent_link=True) |
| 271 | released = models.BooleanField(default=False) |
| 272 | |
| 273 | class VodcastAdmin(admin.ModelAdmin): |
| 274 | list_display = ('name', 'released') |
| 275 | list_editable = ('released',) |
| 276 | |
| 277 | ordering = ('name',) |
| 278 | |
269 | 279 | class Parent(models.Model): |
270 | 280 | name = models.CharField(max_length=128) |
271 | 281 | |
… |
… |
admin.site.register(Subscriber, SubscriberAdmin)
|
303 | 313 | admin.site.register(ExternalSubscriber, ExternalSubscriberAdmin) |
304 | 314 | admin.site.register(OldSubscriber, OldSubscriberAdmin) |
305 | 315 | admin.site.register(Podcast, PodcastAdmin) |
| 316 | admin.site.register(Vodcast, VodcastAdmin) |
306 | 317 | admin.site.register(Parent, ParentAdmin) |
307 | 318 | admin.site.register(EmptyModel, EmptyModelAdmin) |
308 | 319 | admin.site.register(Fabric, FabricAdmin) |
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index d7bce8f..76efdc3 100644
a
|
b
|
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
|
13 | 13 | from django.utils.html import escape |
14 | 14 | |
15 | 15 | # local test models |
16 | | from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Person, Persona, FooAccount, BarAccount, Subscriber, ExternalSubscriber, Podcast, EmptyModel |
| 16 | from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Person, Persona, FooAccount, BarAccount, Subscriber, ExternalSubscriber, Vodcast, Podcast, EmptyModel |
17 | 17 | |
18 | 18 | try: |
19 | 19 | set |
… |
… |
class AdminViewListEditable(TestCase):
|
796 | 796 | response = self.client.get('/test_admin/admin/admin_views/podcast/') |
797 | 797 | self.failUnlessEqual(response.status_code, 200) |
798 | 798 | |
| 799 | def test_inheritance_2(self): |
| 800 | Vodcast.objects.create(name="This Week in Django", released=True) |
| 801 | response = self.client.get('/test_admin/admin/admin_views/vodcast/') |
| 802 | self.failUnlessEqual(response.status_code, 200) |
| 803 | |
799 | 804 | def test_changelist_input_html(self): |
800 | 805 | response = self.client.get('/test_admin/admin/admin_views/person/') |
801 | 806 | # 2 inputs per object(the field and the hidden id field) = 6 |
… |
… |
class AdminActionsTest(TestCase):
|
995 | 1000 | } |
996 | 1001 | response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) |
997 | 1002 | self.failUnlessEqual(response.status_code, 302) |
998 | | |
| 1003 | |
999 | 1004 | def test_model_without_action(self): |
1000 | 1005 | "Tests a ModelAdmin without any action" |
1001 | 1006 | response = self.client.get('/test_admin/admin/admin_views/oldsubscriber/') |
… |
… |
class AdminActionsTest(TestCase):
|
1004 | 1009 | '<input type="checkbox" class="action-select"' not in response.content, |
1005 | 1010 | "Found an unexpected action toggle checkboxbox in response" |
1006 | 1011 | ) |
1007 | | |
| 1012 | |
1008 | 1013 | def test_multiple_actions_form(self): |
1009 | 1014 | """ |
1010 | 1015 | Test that actions come from the form whose submit button was pressed (#10618). |