Ticket #14930: extra_order_by_values_list_with_tests_4.diff

File extra_order_by_values_list_with_tests_4.diff, 5.5 KB (added by fhahn, 3 years ago)

made patch python 2.6 compatible

  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index eda71d2..db82835 100644
    a b class ValuesQuerySet(QuerySet): 
    10171017
    10181018        names = extra_names + field_names + aggregate_names
    10191019
     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
    10201027        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 dict((key, elem) for key, elem in zip(names, row) if key in fields)
    10221031
    10231032    def delete(self):
    10241033        # values().delete() doesn't work currently - make sure it raises an
    class ValuesQuerySet(QuerySet): 
    10641073            self.aggregate_names = None
    10651074
    10661075        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]
    10671081        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)
    10691083        self.query.add_fields(self.field_names, True)
    10701084        if self.aggregate_names is not None:
    10711085            self.query.set_aggregate_mask(self.aggregate_names)
    class ValuesQuerySet(QuerySet): 
    11391153class ValuesListQuerySet(ValuesQuerySet):
    11401154    def iterator(self):
    11411155        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]
    11421160            for row in self.query.get_compiler(self.db).results_iter():
    1143                 yield row[0]
     1161                yield row[len(extra_fields)]
    11441162        elif not self.query.extra_select and not self.query.aggregate_select:
    11451163            for row in self.query.get_compiler(self.db).results_iter():
    11461164                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): 
    15311531        # An empty values() call includes all aliases, including those from an
    15321532        # extra()
    15331533        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')
    15351536        for d in dicts: del d['id']; del d['author_id']
    15361537        self.assertEqual(
    15371538            [sorted(d.items()) for d in dicts],
    class EmptyQuerySetTests(TestCase): 
    19951996
    19961997
    19971998class ValuesQuerysetTests(BaseQuerysetTest):
    1998     def test_flat_values_lits(self):
     1999    def setUp(self):
    19992000        Number.objects.create(num=72)
     2001
     2002    def test_flat_values_list(self):
    20002003        qs = Number.objects.values_list("num")
    20012004        qs = qs.values_list("num", flat=True)
    20022005        self.assertValueQuerysetEqual(
    20032006            qs, [72]
    20042007        )
    20052008
     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
    20062051
    20072052class WeirdQuerysetSlicingTests(BaseQuerysetTest):
    20082053    def setUp(self):
Back to Top