diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 21153dcbb8a..5954cf35f41 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1426,14 +1426,16 @@ class ForeignObject(RelatedField): @staticmethod def get_instance_value_for_fields(instance, fields): ret = [] + opts = instance._meta for field in fields: # Gotcha: in some cases (like fixture loading) a model can have # different values in parent_ptr_id and parent's id. So, use # instance.pk (that is, parent_ptr_id) when asked for instance.id. - opts = instance._meta if field.primary_key: possible_parent_link = opts.get_ancestor_link(field.model) - if not possible_parent_link or possible_parent_link.primary_key: + if (not possible_parent_link or + possible_parent_link.primary_key or + possible_parent_link.model._meta.abstract): ret.append(instance.pk) continue ret.append(getattr(instance, field.attname)) diff --git a/tests/fixtures_regress/fixtures/feature.json b/tests/fixtures_regress/fixtures/feature.json new file mode 100644 index 00000000000..84aa2adcf45 --- /dev/null +++ b/tests/fixtures_regress/fixtures/feature.json @@ -0,0 +1,17 @@ +[ +{ + "fields": { + "channels": [], + "title": "Title of this feature article" + }, + "model": "fixtures_regress.article", + "pk": 1 +}, +{ + "fields": { + "channels": [] + }, + "model": "fixtures_regress.feature", + "pk": 1 +} +] diff --git a/tests/fixtures_regress/models.py b/tests/fixtures_regress/models.py index 95f9488ab75..14f88297602 100644 --- a/tests/fixtures_regress/models.py +++ b/tests/fixtures_regress/models.py @@ -52,7 +52,7 @@ class Child(Parent): data = models.CharField(max_length=10) -# Models to regression test #7572 +# Models to regression test #7572, #20820 class Channel(models.Model): name = models.CharField(max_length=255) @@ -70,6 +70,17 @@ class SpecialArticle(Article): pass +# Models to regression test #22421 +class CommonFeature(Article): + + class Meta: + abstract = True + + +class Feature(CommonFeature): + pass + + # Models to regression test #11428 @python_2_unicode_compatible class Widget(models.Model): diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 61fc66d9280..f99bcbe3787 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -480,6 +480,18 @@ class TestFixtures(TestCase): verbosity=0, ) + def test_ticket_22421(self): + """ + Regression for ticket #22421 -- loaddata on a model that inherits from + a grand-parent model with a M2M but via an abstract parent shouldn't + blow up. + """ + management.call_command( + 'loaddata', + 'feature.json', + verbosity=0, + ) + class NaturalKeyFixtureTests(TestCase):