mirror of
https://github.com/SectorLabs/django-localized-fields.git
synced 2025-04-24 19:32:53 +03:00
Don't double key transform in lookups
In Django 4.2, `process_lhs()` is called for IsNull lookups, which is how this bug came to appear. It was already there and could be reproduced on Django 3.2. The issue is when `LocalizedRef` is combined with a localized lookup. The lookup is unaware of the existing localized ref and adds another transform on top. This results in the expression becoming: ``` field->'en'->'en' ```
This commit is contained in:
parent
25259b8469
commit
e6527fff4c
@ -23,6 +23,7 @@ from django.db.models.lookups import (
|
|||||||
StartsWith,
|
StartsWith,
|
||||||
)
|
)
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
from psqlextra.expressions import HStoreColumn
|
||||||
|
|
||||||
from .fields import LocalizedField
|
from .fields import LocalizedField
|
||||||
|
|
||||||
@ -37,14 +38,33 @@ except ImportError:
|
|||||||
|
|
||||||
class LocalizedLookupMixin:
|
class LocalizedLookupMixin:
|
||||||
def process_lhs(self, qn, connection):
|
def process_lhs(self, qn, connection):
|
||||||
if isinstance(self.lhs, Col):
|
# If the LHS is already a reference to a specific hstore key, there
|
||||||
|
# is nothing to be done since it already references as specific language.
|
||||||
|
if isinstance(self.lhs, HStoreColumn) or isinstance(
|
||||||
|
self.lhs, KeyTransform
|
||||||
|
):
|
||||||
|
return super().process_lhs(qn, connection)
|
||||||
|
|
||||||
|
# If this is something custom expression, we don't really know how to
|
||||||
|
# handle that, so we better do nothing.
|
||||||
|
if not isinstance(self.lhs, Col):
|
||||||
|
return super().process_lhs(qn, connection)
|
||||||
|
|
||||||
|
# Select the key for the current language. We do this so that
|
||||||
|
#
|
||||||
|
# myfield__<lookup>=
|
||||||
|
#
|
||||||
|
# Is converted into:
|
||||||
|
#
|
||||||
|
# myfield__<lookup>__<current language>=
|
||||||
language = translation.get_language() or settings.LANGUAGE_CODE
|
language = translation.get_language() or settings.LANGUAGE_CODE
|
||||||
self.lhs = KeyTransform(language, self.lhs)
|
self.lhs = KeyTransform(language, self.lhs)
|
||||||
|
|
||||||
return super().process_lhs(qn, connection)
|
return super().process_lhs(qn, connection)
|
||||||
|
|
||||||
def get_prep_lookup(self):
|
def get_prep_lookup(self):
|
||||||
# Django 4.0 removed the ability for isnull fields to be something other than a bool
|
# Django 4.0 removed the ability for isnull fields to be something
|
||||||
# We should NOT convert them to strings
|
# other than a bool We should NOT convert them to strings
|
||||||
if isinstance(self.rhs, bool):
|
if isinstance(self.rhs, bool):
|
||||||
return self.rhs
|
return self.rhs
|
||||||
return str(self.rhs)
|
return str(self.rhs)
|
||||||
|
@ -3,6 +3,7 @@ from django.conf import settings
|
|||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
|
||||||
|
from localized_fields.expressions import LocalizedRef
|
||||||
from localized_fields.fields import LocalizedField
|
from localized_fields.fields import LocalizedField
|
||||||
from localized_fields.value import LocalizedValue
|
from localized_fields.value import LocalizedValue
|
||||||
|
|
||||||
@ -49,6 +50,18 @@ class LocalizedLookupsTestCase(TestCase):
|
|||||||
# ensure that hstore lookups still work
|
# ensure that hstore lookups still work
|
||||||
assert self.TestModel.objects.filter(text__ro="text_ro").exists()
|
assert self.TestModel.objects.filter(text__ro="text_ro").exists()
|
||||||
|
|
||||||
|
def test_localized_lookup_specific_isnull(self):
|
||||||
|
self.TestModel.objects.create(
|
||||||
|
text=LocalizedValue(dict(en="text_en", ro="text_ro", nl=None))
|
||||||
|
)
|
||||||
|
|
||||||
|
translation.activate("nl")
|
||||||
|
assert (
|
||||||
|
self.TestModel.objects.annotate(text_localized=LocalizedRef("text"))
|
||||||
|
.filter(text_localized__isnull=True)
|
||||||
|
.exists()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LocalizedRefLookupsTestCase(TestCase):
|
class LocalizedRefLookupsTestCase(TestCase):
|
||||||
"""Tests whether ref lookups properly work with."""
|
"""Tests whether ref lookups properly work with."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user