mirror of
https://github.com/Hopiu/django-modeltranslation.git
synced 2026-04-30 17:54:42 +00:00
fix: Fix handling of expressions in values()/values_list()
This basically duplicates some code from django's implementation. Refs #670
This commit is contained in:
parent
943e90226c
commit
d65ff60007
2 changed files with 47 additions and 4 deletions
|
|
@ -406,8 +406,8 @@ class MultilingualQuerySet(QuerySet):
|
|||
return super(MultilingualQuerySet, self).only(*fields)
|
||||
|
||||
# This method was not present in django-linguo
|
||||
def raw_values(self, *fields):
|
||||
return super(MultilingualQuerySet, self).values(*fields)
|
||||
def raw_values(self, *fields, **expressions):
|
||||
return super(MultilingualQuerySet, self).values(*fields, **expressions)
|
||||
|
||||
def _values(self, *original, **kwargs):
|
||||
selects_all = kwargs.pop('selects_all', False)
|
||||
|
|
@ -429,6 +429,7 @@ class MultilingualQuerySet(QuerySet):
|
|||
if not fields:
|
||||
# Emulate original queryset behaviour: get all fields that are not translation fields
|
||||
fields = self._get_original_fields()
|
||||
fields += tuple(expressions)
|
||||
clone = self._values(*fields, prepare=True, selects_all=selects_all, **expressions)
|
||||
clone._iterable_class = FallbackValuesIterable
|
||||
return clone
|
||||
|
|
@ -447,7 +448,25 @@ class MultilingualQuerySet(QuerySet):
|
|||
if not fields:
|
||||
# Emulate original queryset behaviour: get all fields that are not translation fields
|
||||
fields = self._get_original_fields()
|
||||
clone = self._values(*fields, prepare=True, selects_all=selects_all)
|
||||
|
||||
field_names = {f for f in fields if not hasattr(f, 'resolve_expression')}
|
||||
_fields = []
|
||||
expressions = {}
|
||||
counter = 1
|
||||
for field in fields:
|
||||
if hasattr(field, 'resolve_expression'):
|
||||
field_id_prefix = getattr(field, 'default_alias', field.__class__.__name__.lower())
|
||||
while True:
|
||||
field_id = field_id_prefix + str(counter)
|
||||
counter += 1
|
||||
if field_id not in field_names:
|
||||
break
|
||||
expressions[field_id] = field
|
||||
_fields.append(field_id)
|
||||
else:
|
||||
_fields.append(field)
|
||||
|
||||
clone = self._values(*_fields, prepare=True, selects_all=selects_all, **expressions)
|
||||
clone._iterable_class = (
|
||||
FallbackNamedValuesListIterable
|
||||
if named
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ from django.core.files.storage import default_storage
|
|||
from django.core.management import call_command
|
||||
from django.core.management.base import CommandError
|
||||
from django.db import IntegrityError
|
||||
from django.db.models import Count, F, Q, TextField, Value
|
||||
from django.db.models import CharField, Count, F, Q, TextField, Value
|
||||
from django.db.models.functions import Cast
|
||||
from django.test import TestCase, TransactionTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.translation import get_language, override, trans_real
|
||||
|
|
@ -2993,6 +2994,29 @@ class TestManager(ModeltranslationTestBase):
|
|||
('foo', 2)
|
||||
]
|
||||
|
||||
def test_values_with_expressions(self):
|
||||
manager = models.ManagerTestModel.objects
|
||||
id1 = manager.create(title_en='en', title_de='de').pk
|
||||
|
||||
raw_obj = manager.raw_values('title', str_pk=Cast("pk", output_field=CharField()))[0]
|
||||
obj = manager.values('title', str_pk=Cast("pk", output_field=CharField()))[0]
|
||||
with override('de'):
|
||||
raw_obj2 = manager.raw_values('title', str_pk=Cast("pk", output_field=CharField()))[0]
|
||||
obj2 = manager.values('title', str_pk=Cast("pk", output_field=CharField()))[0]
|
||||
|
||||
# Raw_values returns real database values regardless of current language
|
||||
assert raw_obj['title'] == raw_obj2['title']
|
||||
assert raw_obj['str_pk'] == raw_obj2['str_pk']
|
||||
# Values present language-aware data, from the moment of retrieval
|
||||
assert obj['title'] == 'en'
|
||||
assert obj['str_pk'] == str(id1)
|
||||
assert obj2['title'] == 'de'
|
||||
|
||||
# Values_list behave similarly
|
||||
assert list(manager.values_list('title', Cast("pk", output_field=CharField()))) == [('en', str(id1))]
|
||||
with override('de'):
|
||||
assert list(manager.values_list('title', Cast("pk", output_field=CharField()))) == [('de', str(id1))]
|
||||
|
||||
def test_custom_manager(self):
|
||||
"""Test if user-defined manager is still working"""
|
||||
n = models.CustomManagerTestModel(title='')
|
||||
|
|
|
|||
Loading…
Reference in a new issue