Code

Ticket #12328: bug12328.patch

File bug12328.patch, 3.9 KB (added by marcosmoyano, 4 years ago)

New patch

  • django/db/models/sql/compiler.py

     
    130130        Used when nesting this query inside another. 
    131131        """ 
    132132        obj = self.query.clone() 
    133         obj.clear_ordering(True) 
     133        if obj.low_mark == 0 and obj.high_mark is None: 
     134            obj.clear_ordering(True) 
    134135        obj.bump_prefix() 
    135136        return obj.get_compiler(connection=self.connection).as_sql() 
    136137 
  • django/db/models/query.py

     
    1010from django.db.models.query_utils import Q, select_related_descend, CollectedObjects, CyclicDependency, deferred_class_factory, InvalidQuery 
    1111from django.db.models import signals, sql 
    1212from django.utils.copycompat import deepcopy 
     13from django.db.sql.where import WhereNode 
    1314 
    1415# Used to control how many objects are worked with at once in some cases (e.g. 
    1516# when deleting objects). 
     
    407408        qs.query.add_filter(('pk__in', id_list)) 
    408409        return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()]) 
    409410 
     411    def _verify_before_delete(self, children = []): 
     412        for child in children: 
     413            if isinstance(child, tuple): 
     414                if isinstance(child[-1], QuerySet): 
     415                    assert child[-1].query.can_filter(), \ 
     416                           "Cannot use 'limit' or 'offset' with delete." 
     417            elif isinstance(child, WhereNode): 
     418                self._verify_before_delete(child.children) 
     419 
    410420    def delete(self): 
    411421        """ 
    412422        Deletes the records in the current QuerySet. 
     
    414424        assert self.query.can_filter(), \ 
    415425                "Cannot use 'limit' or 'offset' with delete." 
    416426 
     427        self._verify_before_delete(self.query.where.children) 
     428 
    417429        del_query = self._clone() 
    418430 
    419431        # The delete is actually 2 queries - one to find related objects, 
  • tests/regressiontests/bug12328/tests.py

     
     1from unittest import TestCase 
     2from models import Bug12328 
     3 
     4class TestBug12328(TestCase): 
     5    def test_delete(self): 
     6        Bug12328.objects.create(id=1) 
     7        Bug12328.objects.create(id=2) 
     8        Bug12328.objects.create(id=3) 
     9        expected = Bug12328.objects.filter(id__in=[2,3]) 
     10        Bug12328.objects.filter(id=1).delete() 
     11        self.assertEquals(expected.__repr__(), Bug12328.objects.all().__repr__()) 
     12        Bug12328.objects.create(id=1) 
     13        exp_element = Bug12328.objects.order_by('id')[0:1] 
     14        query = Bug12328.objects.filter(id__in=Bug12328.objects.order_by('id')[0:1].values_list('id', flat=True)) 
     15        query2 = Bug12328.objects.filter(id__in=Bug12328.objects.order_by('id')[0:1]) 
     16        self.assertEquals(exp_element.__repr__(), query.__repr__(), query2.__repr__()) 
     17        # Catch the exception 
     18        try: 
     19            Bug12328.objects.filter(id__in=Bug12328.objects.order_by('id')[0:1]).delete() 
     20        except AssertionError, e: 
     21            self.assertEquals(str(e), "Cannot use 'limit' or 'offset' with delete.") 
  • tests/regressiontests/bug12328/models.py

     
     1from django.db import models 
     2 
     3# Create your models here. 
     4 
     5class Bug12328(models.Model): 
     6    def __unicode__(self): 
     7        return 'M(id=%d)' % self.id