mirror of https://github.com/django/django.git
Fixed #14423 -- corrected incorrect SQL being generated when a nullable, inherited field was used in an exclude. Thanks to PhiR_42 for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14600 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c0248f6f07
commit
0eb31d3dc9
|
@ -921,8 +921,7 @@ class Query(object):
|
||||||
"""
|
"""
|
||||||
opts = model._meta
|
opts = model._meta
|
||||||
field_list = aggregate.lookup.split(LOOKUP_SEP)
|
field_list = aggregate.lookup.split(LOOKUP_SEP)
|
||||||
if (len(field_list) == 1 and
|
if len(field_list) == 1 and aggregate.lookup in self.aggregates:
|
||||||
aggregate.lookup in self.aggregates.keys()):
|
|
||||||
# Aggregate is over an annotation
|
# Aggregate is over an annotation
|
||||||
field_name = field_list[0]
|
field_name = field_list[0]
|
||||||
col = field_name
|
col = field_name
|
||||||
|
@ -1090,11 +1089,14 @@ class Query(object):
|
||||||
if self.alias_map[alias][JOIN_TYPE] == self.LOUTER:
|
if self.alias_map[alias][JOIN_TYPE] == self.LOUTER:
|
||||||
j_col = self.alias_map[alias][RHS_JOIN_COL]
|
j_col = self.alias_map[alias][RHS_JOIN_COL]
|
||||||
entry = self.where_class()
|
entry = self.where_class()
|
||||||
entry.add((Constraint(alias, j_col, None), 'isnull', True), AND)
|
entry.add(
|
||||||
|
(Constraint(alias, j_col, None), 'isnull', True),
|
||||||
|
AND
|
||||||
|
)
|
||||||
entry.negate()
|
entry.negate()
|
||||||
self.where.add(entry, AND)
|
self.where.add(entry, AND)
|
||||||
break
|
break
|
||||||
elif not (lookup_type == 'in'
|
if not (lookup_type == 'in'
|
||||||
and not hasattr(value, 'as_sql')
|
and not hasattr(value, 'as_sql')
|
||||||
and not hasattr(value, '_as_sql')
|
and not hasattr(value, '_as_sql')
|
||||||
and not value) and field.null:
|
and not value) and field.null:
|
||||||
|
|
|
@ -3,12 +3,16 @@ Regression tests for Model inheritance behaviour.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from regressiontests.model_inheritance_regress.models import (
|
|
||||||
Place, Restaurant, ItalianRestaurant, ParkingLot, ParkingLot2,
|
from models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
|
||||||
ParkingLot3, Supplier, Wholesaler, Child, SelfRefChild, ArticleWithAuthor,
|
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
|
||||||
M2MChild, QualityControl, DerivedM, Person, BirthdayParty, BachelorParty,
|
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
|
||||||
MessyBachelorParty, InternalCertificationAudit)
|
Person, BirthdayParty, BachelorParty, MessyBachelorParty,
|
||||||
|
InternalCertificationAudit)
|
||||||
|
|
||||||
|
|
||||||
class ModelInheritanceTest(TestCase):
|
class ModelInheritanceTest(TestCase):
|
||||||
def test_model_inheritance(self):
|
def test_model_inheritance(self):
|
||||||
|
@ -355,7 +359,10 @@ class ModelInheritanceTest(TestCase):
|
||||||
self.assertEqual(parties, [bachelor, messy_parent])
|
self.assertEqual(parties, [bachelor, messy_parent])
|
||||||
|
|
||||||
def test_11369(self):
|
def test_11369(self):
|
||||||
"""verbose_name_plural correctly inherited from ABC if inheritance chain includes an abstract model."""
|
"""
|
||||||
|
verbose_name_plural correctly inherited from ABC if inheritance chain
|
||||||
|
includes an abstract model.
|
||||||
|
"""
|
||||||
# Regression test for #11369: verbose_name_plural should be inherited
|
# Regression test for #11369: verbose_name_plural should be inherited
|
||||||
# from an ABC even when there are one or more intermediate
|
# from an ABC even when there are one or more intermediate
|
||||||
# abstract models in the inheritance chain, for consistency with
|
# abstract models in the inheritance chain, for consistency with
|
||||||
|
@ -364,3 +371,18 @@ class ModelInheritanceTest(TestCase):
|
||||||
InternalCertificationAudit._meta.verbose_name_plural,
|
InternalCertificationAudit._meta.verbose_name_plural,
|
||||||
u'Audits'
|
u'Audits'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_inherited_nullable_exclude(self):
|
||||||
|
obj = SelfRefChild.objects.create(child_data=37, parent_data=42)
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
SelfRefParent.objects.exclude(self_data=72), [
|
||||||
|
obj.pk
|
||||||
|
],
|
||||||
|
attrgetter("pk")
|
||||||
|
)
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
SelfRefChild.objects.exclude(self_data=72), [
|
||||||
|
obj.pk
|
||||||
|
],
|
||||||
|
attrgetter("pk")
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue