app/django/db/models/query_utils.py
author Todd Larsen <tlarsen@google.com>
Fri, 03 Oct 2008 01:32:34 +0000
changeset 263 9b39d93b677f
parent 54 03e267d67478
child 323 ff1a9aa48cfd
permissions -rw-r--r--
Make findNearestUsers() code in soc/logic/site/id_user.py more generic and move it to soc/logic/model.py. Orginal findNearest...() functions in id_user.py are now convenience wrappers. Add typed-query string construction functions to model.py. Move getFulLClassName() from key_name.py model.py, since it has more to do with Model types than key names. Swap 'offset' and 'limit' and make 'limit' arguments non-optional. Also, stop adding 1 inside the ...ForLimitAndOffset() functions and make the callers do it (since it was being added for a very UI-specific reason of whether or not to display a "Next>" link). Patch by: Todd Larsen Review by: Pawel Solyga Review URL: http://codereviews.googleopensourceprograms.com/1401

"""
Various data structures used in query construction.

Factored out from django.db.models.query so that they can also be used by other
modules without getting into circular import difficulties.
"""

from copy import deepcopy

from django.utils import tree

class QueryWrapper(object):
    """
    A type that indicates the contents are an SQL fragment and the associate
    parameters. Can be used to pass opaque data to a where-clause, for example.
    """
    def __init__(self, sql, params):
        self.data = sql, params

class Q(tree.Node):
    """
    Encapsulates filters as objects that can then be combined logically (using
    & and |).
    """
    # Connection types
    AND = 'AND'
    OR = 'OR'
    default = AND

    def __init__(self, *args, **kwargs):
        super(Q, self).__init__(children=list(args) + kwargs.items())

    def _combine(self, other, conn):
        if not isinstance(other, Q):
            raise TypeError(other)
        obj = deepcopy(self)
        obj.add(other, conn)
        return obj

    def __or__(self, other):
        return self._combine(other, self.OR)

    def __and__(self, other):
        return self._combine(other, self.AND)

    def __invert__(self):
        obj = deepcopy(self)
        obj.negate()
        return obj