Fix #19524 -- Incorrect caching of parents of unsaved model instances.

Thanks qcwxezdas for the report. Refs #13839.
This commit is contained in:
Aymeric Augustin 2012-12-28 23:16:13 +01:00
parent 37b3fd27ae
commit e9c24bef74
5 changed files with 48 additions and 4 deletions

View File

@ -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

View File

@ -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
qs = queryset.filter(**{self.fk.name: self.instance})
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)

View File

@ -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])

View File

@ -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

View File

@ -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):