From defc37c7a539dff1e4af96e7d13856519befe585 Mon Sep 17 00:00:00 2001 From: Suyeol Jeon Date: Wed, 4 May 2022 15:25:53 +0900 Subject: [PATCH] fix: Do not include annotation fields when selecting specific fields (#634) --- modeltranslation/manager.py | 9 ++++++--- modeltranslation/tests/tests.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/modeltranslation/manager.py b/modeltranslation/manager.py index 3de1ee6e..bf6e7238 100644 --- a/modeltranslation/manager.py +++ b/modeltranslation/manager.py @@ -414,8 +414,9 @@ def raw_values(self, *fields): def _values(self, *original, **kwargs): if not kwargs.pop('prepare', False): return super(MultilingualQuerySet, self)._values(*original, **kwargs) + selects_all = kwargs.pop('selects_all', False) new_fields, translation_fields = append_fallback(self.model, original) - annotation_keys = set(self.query.annotation_select.keys()) + annotation_keys = set(self.query.annotation_select.keys()) if selects_all else set() new_fields.update(annotation_keys) clone = super(MultilingualQuerySet, self)._values(*list(new_fields), **kwargs) clone.original_fields = tuple(original) @@ -427,10 +428,11 @@ def _values(self, *original, **kwargs): def values(self, *fields, **expressions): if not self._rewrite: return super(MultilingualQuerySet, self).values(*fields, **expressions) + selects_all = not fields 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, **expressions) + clone = self._values(*fields, prepare=True, selects_all=selects_all, **expressions) clone._iterable_class = FallbackValuesIterable return clone @@ -445,10 +447,11 @@ def values_list(self, *fields, **kwargs): raise TypeError( "'flat' is not valid when values_list is " "called with more than one field." ) + selects_all = not fields 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) + clone = self._values(*fields, prepare=True, selects_all=selects_all) clone._iterable_class = ( FallbackFlatValuesListIterable if flat else FallbackValuesListIterable ) diff --git a/modeltranslation/tests/tests.py b/modeltranslation/tests/tests.py index 9cc5226f..7ccf3211 100644 --- a/modeltranslation/tests/tests.py +++ b/modeltranslation/tests/tests.py @@ -2919,6 +2919,17 @@ def test_values(self): id1, ) + # custom annotation with fields specified + self.assertEqual( + list(manager.filter(id=id1).annotate(custom_id=F('id')).values_list('id'))[0], + (id1,), + ) + self.assertIsNone( + list(manager.filter(id=id1).annotate(custom_id=F('id')).values('id'))[0].get( + 'custom_id' + ), + ) + def test_values_list_annotation(self): models.TestModel(title='foo').save() models.TestModel(title='foo').save()