Commit 5097d3c5 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

[1.5.x] Fix #19524 -- Incorrect caching of parents of unsaved model instances.

Thanks qcwxezdas for the report. Refs #13839.

Backport of e9c24bef.
parent be425900
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -583,6 +583,15 @@ class Model(six.with_metaclass(ModelBase, object)):

                if field:
                    setattr(self, field.attname, self._get_pk_val(parent._meta))
                    # Since we didn't have an instance of the parent handy, we
                    # set attname directly, bypassing the descriptor.
                    # Invalidate the related object cache, in case it's been
                    # accidentally populated. A fresh instance will be
                    # re-built from the database if necessary.
                    cache_name = field.get_cache_name()
                    if hasattr(self, cache_name):
                        delattr(self, cache_name)

            if meta.proxy:
                return

+4 −1
Original line number Diff line number Diff line
@@ -692,7 +692,10 @@ class BaseInlineFormSet(BaseModelFormSet):
        self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
        if queryset is None:
            queryset = self.model._default_manager
        if self.instance.pk:
            qs = queryset.filter(**{self.fk.name: self.instance})
        else:
            qs = queryset.none()
        super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix,
                                                queryset=qs, **kwargs)

+5 −1
Original line number Diff line number Diff line
@@ -124,6 +124,9 @@ class ChildModel1Inline(admin.TabularInline):
class ChildModel2Inline(admin.StackedInline):
    model = ChildModel2

# admin for #19524
class SightingInline(admin.TabularInline):
    model = Sighting

site.register(TitleCollection, inlines=[TitleInline])
# Test bug #12561 and #12778
@@ -142,3 +145,4 @@ site.register(Author, AuthorAdmin)
site.register(CapoFamiglia, inlines=[ConsigliereInline, SottoCapoInline])
site.register(ProfileCollection, inlines=[ProfileInline])
site.register(ParentModelWithCustomPk, inlines=[ChildModel1Inline, ChildModel2Inline])
site.register(ExtraTerrestrial, inlines=[SightingInline])
+12 −1
Original line number Diff line number Diff line
@@ -90,7 +90,6 @@ class Inner4Tabular(models.Model):
    dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.")
    holder = models.ForeignKey(Holder4)


# Models for #12749

class Person(models.Model):
@@ -133,6 +132,7 @@ class Chapter(models.Model):


# Models for #16838

class CapoFamiglia(models.Model):
    name = models.CharField(max_length=100)

@@ -170,6 +170,17 @@ class ChildModel2(models.Model):
    def get_absolute_url(self):
        return '/child_model2/'

# Models for #19524

class LifeForm(models.Model):
    pass

class ExtraTerrestrial(LifeForm):
    name = models.CharField(max_length=100)

class Sighting(models.Model):
    et = models.ForeignKey(ExtraTerrestrial)
    place = models.CharField(max_length=100)

# Other models

+18 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ from .admin import InnerInline, TitleInline, site
from .models import (Holder, Inner, Holder2, Inner2, Holder3, Inner3, Person,
    OutfitItem, Fashionista, Teacher, Parent, Child, Author, Book, Profile,
    ProfileCollection, ParentModelWithCustomPk, ChildModel1, ChildModel2,
    Title)
    Sighting, Title)


@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
@@ -172,6 +172,23 @@ class TestInline(TestCase):
        self.assertContains(response, child1_shortcut)
        self.assertContains(response, child2_shortcut)

    def test_create_inlines_on_inherited_model(self):
        """
        Ensure that an object can be created with inlines when it inherits
        another class. Bug #19524.
        """
        data = {
            'name': 'Martian',
            'sighting_set-TOTAL_FORMS': 1,
            'sighting_set-INITIAL_FORMS': 0,
            'sighting_set-MAX_NUM_FORMS': 0,
            'sighting_set-0-place': 'Zone 51',
            '_save': 'Save',
        }
        response = self.client.post('/admin/admin_inlines/extraterrestrial/add/', data)
        self.assertEqual(response.status_code, 302)
        self.assertEqual(Sighting.objects.filter(et__name='Martian').count(), 1)


@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class TestInlineMedia(TestCase):