Ticket #14930: extra_order_by_values_list_with_tests_3.diff
File extra_order_by_values_list_with_tests_3.diff, 5.5 KB (added by , 12 years ago) |
---|
-
django/db/models/query.py
diff --git a/django/db/models/query.py b/django/db/models/query.py index eda71d2..01e3b9f 100644
a b class ValuesQuerySet(QuerySet): 1017 1017 1018 1018 names = extra_names + field_names + aggregate_names 1019 1019 1020 # If a field list has been specified, use it. Otherwise, use the 1021 # full list of fields, including extras and aggregates. 1022 if self._fields: 1023 fields = list(self._fields) + [f for f in aggregate_names if f not in self._fields] 1024 else: 1025 fields = names 1026 1020 1027 for row in self.query.get_compiler(self.db).results_iter(): 1021 yield dict(zip(names, row)) 1028 # removes the non-necessary fields in the intersection 1029 # between names and fields 1030 yield {key: elem for key, elem in zip(names, row) if key in fields} 1022 1031 1023 1032 def delete(self): 1024 1033 # values().delete() doesn't work currently - make sure it raises an … … class ValuesQuerySet(QuerySet): 1064 1073 self.aggregate_names = None 1065 1074 1066 1075 self.query.select = [] 1076 # add fields that are required by order_by or extra_order_by and 1077 # present in extra_select to extra_mask 1078 order_by_fields = list(self.query.order_by or []) + list(self.query.extra_order_by or []) 1079 extra_mask_names = list(self.extra_names or []) +\ 1080 [n for n in order_by_fields if n in self.query.extra_select] 1067 1081 if self.extra_names is not None: 1068 self.query.set_extra_mask( self.extra_names)1082 self.query.set_extra_mask(extra_mask_names) 1069 1083 self.query.add_fields(self.field_names, True) 1070 1084 if self.aggregate_names is not None: 1071 1085 self.query.set_aggregate_mask(self.aggregate_names) … … class ValuesQuerySet(QuerySet): 1139 1153 class ValuesListQuerySet(ValuesQuerySet): 1140 1154 def iterator(self): 1141 1155 if self.flat and len(self._fields) == 1: 1156 # get fields that were added to extra_select_mask but are not 1157 # expected in the value_list (e.g: a field was added to 1158 # extra_select_mask because it was needed be an order by clause) 1159 extra_fields = [f for f in self.query.extra_select_mask if f not in self._fields] 1142 1160 for row in self.query.get_compiler(self.db).results_iter(): 1143 yield row[ 0]1161 yield row[len(extra_fields)] 1144 1162 elif not self.query.extra_select and not self.query.aggregate_select: 1145 1163 for row in self.query.get_compiler(self.db).results_iter(): 1146 1164 yield tuple(row) -
tests/regressiontests/queries/tests.py
diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py index 4adf076..d8bb7fc 100644
a b class Queries5Tests(TestCase): 1531 1531 # An empty values() call includes all aliases, including those from an 1532 1532 # extra() 1533 1533 qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'}) 1534 dicts = qs.values().order_by('id') 1534 dicts = qs.values() 1535 dicts = dicts.order_by('id') 1535 1536 for d in dicts: del d['id']; del d['author_id'] 1536 1537 self.assertEqual( 1537 1538 [sorted(d.items()) for d in dicts], … … class EmptyQuerySetTests(TestCase): 1995 1996 1996 1997 1997 1998 class ValuesQuerysetTests(BaseQuerysetTest): 1998 def test_flat_values_lits(self):1999 def setUp(self): 1999 2000 Number.objects.create(num=72) 2001 2002 def test_flat_values_list(self): 2000 2003 qs = Number.objects.values_list("num") 2001 2004 qs = qs.values_list("num", flat=True) 2002 2005 self.assertValueQuerysetEqual( 2003 2006 qs, [72] 2004 2007 ) 2005 2008 2009 def test_extra_values(self): 2010 # testing for ticket 14930 issues 2011 qs = Number.objects.extra(select={'value_plus_one': 'num+1', 'value_minus_one': 'num-1' }) 2012 qs = qs.order_by('value_minus_one') 2013 qs = qs.values('num') 2014 identity = lambda x:x 2015 self.assertQuerysetEqual(qs, [{'num': 72}], identity) 2016 2017 def test_extra_values_order_twice(self): 2018 # testing for ticket 14930 issues 2019 qs = Number.objects.extra(select={'value_plus_one': 'num+1', 'value_minus_one': 'num-1' }) 2020 qs = qs.order_by('value_minus_one').order_by('value_plus_one') 2021 qs = qs.values('num') 2022 identity = lambda x:x 2023 self.assertQuerysetEqual(qs, [{'num': 72}], identity) 2024 2025 def test_extra_values_order_in_extra(self): 2026 # testing for ticket 14930 issues 2027 qs = Number.objects.extra( 2028 select={'value_plus_one': 'num+1', 'value_minus_one': 'num-1' }, 2029 order_by=['value_minus_one']) 2030 qs = qs.values('num') 2031 identity = lambda x:x 2032 self.assertQuerysetEqual(qs, [{'num': 72}], identity) 2033 2034 def test_extra_values_list(self): 2035 # testing for ticket 14930 issues 2036 qs = Number.objects.extra(select={'value_plus_one': 'num+1'}) 2037 qs = qs.order_by('value_plus_one') 2038 qs = qs.values_list('num') 2039 identity = lambda x:x 2040 self.assertQuerysetEqual(qs, [(72,)], identity) 2041 2042 def test_flat_extra_values_list(self): 2043 # testing for ticket 14930 issues 2044 qs = Number.objects.extra(select={'value_plus_one': 'num+1'}) 2045 qs = qs.order_by('value_plus_one') 2046 qs = qs.values_list('num', flat=True) 2047 identity = lambda x:x 2048 self.assertQuerysetEqual(qs, [72], identity) 2049 2050 2006 2051 2007 2052 class WeirdQuerysetSlicingTests(BaseQuerysetTest): 2008 2053 def setUp(self):