Ticket #18631: ticket_18631_poc.diff

File ticket_18631_poc.diff, 2.7 KB (added by akaariai, 3 years ago)
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index 0f1d87c..526bc94 100644
    a b class QuerySet(object): 
    4242        self._prefetch_related_lookups = []
    4343        self._prefetch_done = False
    4444        self._known_related_object = None       # (attname, rel_obj)
     45        self._gimme_called = False
    4546
    4647    ########################
    4748    # PYTHON MAGIC METHODS #
    class QuerySet(object): 
    541542        else:
    542543            forced_managed = False
    543544        try:
    544             rows = query.get_compiler(self.db).execute_sql(None)
     545            if self._gimme_called:
     546                ret = query.get_compiler(self.db)
     547            else:
     548                ret = query.get_compiler(self.db).execute_sql(None)
    545549            if forced_managed:
    546550                transaction.commit(using=self.db)
    547551            else:
    class QuerySet(object): 
    550554            if forced_managed:
    551555                transaction.leave_transaction_management(using=self.db)
    552556        self._result_cache = None
    553         return rows
     557        return ret
    554558    update.alters_data = True
    555559
    556560    def _update(self, values):
    class QuerySet(object): 
    932936            return obj.query.get_compiler(connection=connection).as_nested_sql()
    933937        raise ValueError("Can't do subqueries with queries on different DBs.")
    934938
     939    def _gimme_qs(self):
     940        """
     941        Calling this debug-helper method will give a queryset instead of
     942        executing the query when calling a terminal queries. Usage example:
     943            qs = qs._gimme_qs().update(foo='bar')
     944            assertTrue('footable' in qs.query.alias_map)
     945
     946        The terminal method must be called directly after _gimme_qs().
     947        """
     948        self._gimme_called = True
     949        return self
     950
    935951    # When used as part of a nested query, a queryset will never be an "always
    936952    # empty" result.
    937953    value_annotation = True
  • tests/modeltests/update/tests.py

    diff --git a/tests/modeltests/update/tests.py b/tests/modeltests/update/tests.py
    index 7a1177c..4b9da1f 100644
    a b  
    11from __future__ import absolute_import, unicode_literals
    22
     3from django.db.models import Count
    34from django.test import TestCase
    45
    56from .models import A, B, C, D, DataPoint, RelatedPoint
    class AdvancedTests(TestCase): 
    116117        method = DataPoint.objects.all()[:2].update
    117118        self.assertRaises(AssertionError, method,
    118119            another_value='another thing')
     120
     121    def test_update_annotate(self):
     122        qs = DataPoint.objects.annotate(Count('relatedpoint__name'))._gimme_qs().update(value='foo')
     123        print qs.query
Back to Top