Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

…nstances.

Thanks qcwxezdas for the report. Refs #13839.

Backport of e9c24be.
  • Loading branch information...
commit 5097d3c5faab2b6582c4cebee2b265fcdbb893eb 1 parent be42590
Aymeric Augustin authored December 28, 2012
9  django/db/models/base.py
@@ -583,6 +583,15 @@ def save_base(self, raw=False, cls=None, origin=None, force_insert=False,
583 583
 
584 584
                 if field:
585 585
                     setattr(self, field.attname, self._get_pk_val(parent._meta))
  586
+                    # Since we didn't have an instance of the parent handy, we
  587
+                    # set attname directly, bypassing the descriptor.
  588
+                    # Invalidate the related object cache, in case it's been
  589
+                    # accidentally populated. A fresh instance will be
  590
+                    # re-built from the database if necessary.
  591
+                    cache_name = field.get_cache_name()
  592
+                    if hasattr(self, cache_name):
  593
+                        delattr(self, cache_name)
  594
+
586 595
             if meta.proxy:
587 596
                 return
588 597
 
5  django/forms/models.py
@@ -692,7 +692,10 @@ def __init__(self, data=None, files=None, instance=None,
692 692
         self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
693 693
         if queryset is None:
694 694
             queryset = self.model._default_manager
695  
-        qs = queryset.filter(**{self.fk.name: self.instance})
  695
+        if self.instance.pk:
  696
+            qs = queryset.filter(**{self.fk.name: self.instance})
  697
+        else:
  698
+            qs = queryset.none()
696 699
         super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix,
697 700
                                                 queryset=qs, **kwargs)
698 701
 
6  tests/regressiontests/admin_inlines/admin.py
@@ -124,6 +124,9 @@ class ChildModel1Inline(admin.TabularInline):
124 124
 class ChildModel2Inline(admin.StackedInline):
125 125
     model = ChildModel2
126 126
 
  127
+# admin for #19524
  128
+class SightingInline(admin.TabularInline):
  129
+    model = Sighting
127 130
 
128 131
 site.register(TitleCollection, inlines=[TitleInline])
129 132
 # Test bug #12561 and #12778
@@ -141,4 +144,5 @@ class ChildModel2Inline(admin.StackedInline):
141 144
 site.register(Author, AuthorAdmin)
142 145
 site.register(CapoFamiglia, inlines=[ConsigliereInline, SottoCapoInline])
143 146
 site.register(ProfileCollection, inlines=[ProfileInline])
144  
-site.register(ParentModelWithCustomPk, inlines=[ChildModel1Inline, ChildModel2Inline])
  147
+site.register(ParentModelWithCustomPk, inlines=[ChildModel1Inline, ChildModel2Inline])
  148
+site.register(ExtraTerrestrial, inlines=[SightingInline])
13  tests/regressiontests/admin_inlines/models.py
@@ -90,7 +90,6 @@ class Inner4Tabular(models.Model):
90 90
     dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.")
91 91
     holder = models.ForeignKey(Holder4)
92 92
 
93  
-
94 93
 # Models for #12749
95 94
 
96 95
 class Person(models.Model):
@@ -133,6 +132,7 @@ class Chapter(models.Model):
133 132
 
134 133
 
135 134
 # Models for #16838
  135
+
136 136
 class CapoFamiglia(models.Model):
137 137
     name = models.CharField(max_length=100)
138 138
 
@@ -170,6 +170,17 @@ class ChildModel2(models.Model):
170 170
     def get_absolute_url(self):
171 171
         return '/child_model2/'
172 172
 
  173
+# Models for #19524
  174
+
  175
+class LifeForm(models.Model):
  176
+    pass
  177
+
  178
+class ExtraTerrestrial(LifeForm):
  179
+    name = models.CharField(max_length=100)
  180
+
  181
+class Sighting(models.Model):
  182
+    et = models.ForeignKey(ExtraTerrestrial)
  183
+    place = models.CharField(max_length=100)
173 184
 
174 185
 # Other models
175 186
 
19  tests/regressiontests/admin_inlines/tests.py
@@ -12,7 +12,7 @@
12 12
 from .models import (Holder, Inner, Holder2, Inner2, Holder3, Inner3, Person,
13 13
     OutfitItem, Fashionista, Teacher, Parent, Child, Author, Book, Profile,
14 14
     ProfileCollection, ParentModelWithCustomPk, ChildModel1, ChildModel2,
15  
-    Title)
  15
+    Sighting, Title)
16 16
 
17 17
 
18 18
 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
@@ -172,6 +172,23 @@ def test_custom_pk_shortcut(self):
172 172
         self.assertContains(response, child1_shortcut)
173 173
         self.assertContains(response, child2_shortcut)
174 174
 
  175
+    def test_create_inlines_on_inherited_model(self):
  176
+        """
  177
+        Ensure that an object can be created with inlines when it inherits
  178
+        another class. Bug #19524.
  179
+        """
  180
+        data = {
  181
+            'name': 'Martian',
  182
+            'sighting_set-TOTAL_FORMS': 1,
  183
+            'sighting_set-INITIAL_FORMS': 0,
  184
+            'sighting_set-MAX_NUM_FORMS': 0,
  185
+            'sighting_set-0-place': 'Zone 51',
  186
+            '_save': 'Save',
  187
+        }
  188
+        response = self.client.post('/admin/admin_inlines/extraterrestrial/add/', data)
  189
+        self.assertEqual(response.status_code, 302)
  190
+        self.assertEqual(Sighting.objects.filter(et__name='Martian').count(), 1)
  191
+
175 192
 
176 193
 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
177 194
 class TestInlineMedia(TestCase):

0 notes on commit 5097d3c

Simon Charette

This introduce a regression with related managers on 1.5.X since none returns an EmptyQuerySet instance while it works fine on master since none sets the underlying query to empty while returning a queryset.__class__ instance. I'll open a ticket with a failing test case.

Aymeric Augustin

I saw that you and Anssi came up with a patch in https://code.djangoproject.com/ticket/19652.

For added safety I committed 9328ef0.

Please sign in to comment.
Something went wrong with that request. Please try again.