Fixed #26153 -- Reallowed Q-objects in ForeignObject.get_extra_descriptor_filter().
This commit is contained in:
parent
1d86d4c72b
commit
353aecbf8c
|
@ -8,6 +8,7 @@ from django.apps import apps
|
|||
from django.core import checks, exceptions
|
||||
from django.db import connection, router
|
||||
from django.db.backends import utils
|
||||
from django.db.models import Q
|
||||
from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL
|
||||
from django.db.models.query_utils import PathInfo
|
||||
from django.db.models.utils import make_model_tuple
|
||||
|
@ -337,8 +338,13 @@ class RelatedField(Field):
|
|||
rh_field.attname: getattr(obj, lh_field.attname)
|
||||
for lh_field, rh_field in self.related_fields
|
||||
}
|
||||
base_filter.update(self.get_extra_descriptor_filter(obj) or {})
|
||||
return base_filter
|
||||
descriptor_filter = self.get_extra_descriptor_filter(obj)
|
||||
base_q = Q(**base_filter)
|
||||
if isinstance(descriptor_filter, dict):
|
||||
return base_q & Q(**descriptor_filter)
|
||||
elif descriptor_filter:
|
||||
return base_q & descriptor_filter
|
||||
return base_q
|
||||
|
||||
@property
|
||||
def swappable_setting(self):
|
||||
|
|
|
@ -166,7 +166,7 @@ class ForwardManyToOneDescriptor(object):
|
|||
rel_obj = None
|
||||
else:
|
||||
qs = self.get_queryset(instance=instance)
|
||||
qs = qs.filter(**self.field.get_reverse_related_filter(instance))
|
||||
qs = qs.filter(self.field.get_reverse_related_filter(instance))
|
||||
# Assuming the database enforces foreign keys, this won't fail.
|
||||
rel_obj = qs.get()
|
||||
# If this is a one-to-one relation, set the reverse accessor
|
||||
|
|
|
@ -17,3 +17,7 @@ Bugfixes
|
|||
|
||||
* Added system checks for query name clashes of hidden relationships
|
||||
(:ticket:`26162`).
|
||||
|
||||
* Fixed a regression for cases where
|
||||
``ForeignObject.get_extra_descriptor_filter()`` returned a ``Q`` object
|
||||
(:ticket:`26153`).
|
||||
|
|
|
@ -44,6 +44,11 @@ class ActiveTranslationField(models.ForeignObject):
|
|||
setattr(cls, self.name, ArticleTranslationDescriptor(self))
|
||||
|
||||
|
||||
class ActiveTranslationFieldWithQ(ActiveTranslationField):
|
||||
def get_extra_descriptor_filter(self, instance):
|
||||
return models.Q(lang=get_language())
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Article(models.Model):
|
||||
active_translation = ActiveTranslationField(
|
||||
|
@ -54,6 +59,14 @@ class Article(models.Model):
|
|||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
)
|
||||
active_translation_q = ActiveTranslationFieldWithQ(
|
||||
'ArticleTranslation',
|
||||
from_fields=['id'],
|
||||
to_fields=['article'],
|
||||
related_name='+',
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
)
|
||||
pub_date = models.DateField()
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -458,3 +458,16 @@ class TestModelCheckTests(SimpleTestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(Child._meta.get_field('parent').check(from_model=Child), [])
|
||||
|
||||
|
||||
class TestExtraJoinFilterQ(TestCase):
|
||||
@translation.override('fi')
|
||||
def test_extra_join_filter_q(self):
|
||||
a = Article.objects.create(pub_date=datetime.datetime.today())
|
||||
ArticleTranslation.objects.create(article=a, lang='fi', title='title', body='body')
|
||||
qs = Article.objects.all()
|
||||
with self.assertNumQueries(2):
|
||||
self.assertEqual(qs[0].active_translation_q.title, 'title')
|
||||
qs = qs.select_related('active_translation_q')
|
||||
with self.assertNumQueries(1):
|
||||
self.assertEqual(qs[0].active_translation_q.title, 'title')
|
||||
|
|
Loading…
Reference in New Issue