Django

Code

Changeset 7461

Show
Ignore:
Timestamp:
04/25/08 10:02:25 (4 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Simplify the way filters are passed to the Query class.

This removes a lot of the complexity for handling exclude() calls and results
in more efficient code. I feel a bit stupid for not having spotted this earlier.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/query.py

    r7451 r7461  
    44from django.db import connection, transaction, IntegrityError 
    55from django.db.models.fields import DateField, FieldDoesNotExist 
    6 from django.db.models.query_utils import Q, not_q 
     6from django.db.models.query_utils import Q 
    77from django.db.models import signals, sql 
    88from django.dispatch import dispatcher 
     
    356356        set. 
    357357        """ 
    358         return self._filter_or_exclude(None, *args, **kwargs) 
     358        return self._filter_or_exclude(False, *args, **kwargs) 
    359359 
    360360    def exclude(self, *args, **kwargs): 
     
    363363        set. 
    364364        """ 
    365         return self._filter_or_exclude(not_q, *args, **kwargs) 
    366  
    367     def _filter_or_exclude(self, mapper, *args, **kwargs): 
    368         # mapper is a callable used to transform Q objects, 
    369         # or None for identity transform. 
    370         if mapper is None: 
    371             mapper = lambda x: x 
     365        return self._filter_or_exclude(True, *args, **kwargs) 
     366 
     367    def _filter_or_exclude(self, negate, *args, **kwargs): 
    372368        if args or kwargs: 
    373369            assert self.query.can_filter(), \ 
    374                 "Cannot filter a query once a slice has been taken." 
     370                    "Cannot filter a query once a slice has been taken." 
    375371 
    376372        clone = self._clone() 
    377         if kwargs
    378             clone.query.add_q(mapper(Q(**kwargs))) 
    379         for arg in args
    380             clone.query.add_q(mapper(arg)) 
     373        if negate
     374            clone.query.add_q(~Q(*args, **kwargs)) 
     375        else
     376            clone.query.add_q(Q(*args, **kwargs)) 
    381377        return clone 
    382378 
  • django/branches/queryset-refactor/django/db/models/query_utils.py

    r7245 r7461  
    2929 
    3030    def __init__(self, *args, **kwargs): 
    31         if args and kwargs: 
    32             raise TypeError('Use positional *or* kwargs; not both!') 
    33         nodes = list(args) + kwargs.items() 
    34         super(Q, self).__init__(children=nodes) 
     31        super(Q, self).__init__(children=list(args) + kwargs.items()) 
    3532 
    3633    def _combine(self, other, conn): 
     
    5249        return obj 
    5350 
    54 def not_q(q): 
    55     return ~q 
    56  
  • django/branches/queryset-refactor/django/db/models/sql/query.py

    r7459 r7461  
    970970                self.promote_alias(table) 
    971971 
    972         entry = (alias, col, field, lookup_type, value) 
    973         if negate and single_filter: 
    974             # This case is when we're doing the Q2 filter in exclude(Q1, Q2). 
    975             # It's different from exclude(Q1).exclude(Q2). 
    976             for node in self.where.children: 
    977                 if getattr(node, 'negated', False): 
    978                     node.add(entry, connector) 
    979                     merged = True 
    980                     break 
    981         else: 
    982             self.where.add(entry, connector) 
    983             merged = False 
    984  
     972        self.where.add((alias, col, field, lookup_type, value), connector) 
    985973        if negate: 
     974            self.where.negate() 
    986975            for alias in join_list: 
    987976                self.promote_alias(alias) 
    988             if not merged: 
    989                 self.where.negate() 
    990977            if final > 1 and lookup_type != 'isnull': 
    991978                for alias in join_list: 
     
    10201007                self.add_q(child) 
    10211008                self.where.end_subtree() 
     1009                if q_object.negated: 
     1010                    self.where.children[-1].negate() 
    10221011            else: 
    10231012                self.add_filter(child, connector, q_object.negated,