Ticket #12725: Q.or_.diff

File Q.or_.diff, 2.8 KB (added by Jeff Balogh, 14 years ago)

The Q.or_ class method combines a bunch of Q objects and keyword arguments without all the cloning that occurs using |.

  • django/db/models/query_utils.py

    diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
    index 8e804ec..cf9802e 100644
    a b class Q(tree.Node):  
    168168        obj.negate()
    169169        return obj
    170170
     171    @classmethod
     172    def or_(cls, *args, **kwargs):
     173        """
     174        OR together a bunch of Q objects and keyword arguments without cloning.
     175        """
     176        query = cls()
     177        for q in args:
     178            query.add(q, cls.OR)
     179        for key, value in kwargs.items():
     180            query.add(Q(**{key: value}), cls.OR)
     181        return query
     182
    171183class DeferredAttribute(object):
    172184    """
    173185    A wrapper for a deferred-loading field. When the value is read from this
  • docs/topics/db/queries.txt

    diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt
    index be16a2b..341b05a 100644
    a b precede the definition of any keyword arguments. For example::  
    692692
    693693... would not be valid.
    694694
     695If you want to "OR" together a lot of arguments at once, it's more efficient to
     696use ``Q.or_``.  ``Q.or_`` is a class method that takes any number of Q objects
     697and keyword arguments and combines them with ``OR``, returning a new ``Q``
     698object.  As mentioned above, all ``Q`` objects must come before any keyword
     699arguments.
     700
     701The following queries are all equivalent::
     702
     703    Q(question__startswith='Who') | Q(pub_date__year=2005)
     704
     705    Q.or_(question__startswith='Who', pub_date__year=2005)
     706
     707    Q.or_(Q(question__startswith='Who'), pub_date__year=2005)
     708
     709    Q.or_(Q(question__startswith='Who'), Q(pub_date__year=2005))
     710
    695711.. seealso::
    696712
    697713    The `OR lookups examples`_ in the Django unit tests show some possible uses
  • tests/regressiontests/queries/models.py

    diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
    index 43c8437..455334b 100644
    a b constraints.  
    418418>>> Number.objects.filter(Q(num__gt=7) & Q(num__lt=12) | Q(num__lt=4))
    419419[<Number: 8>]
    420420
     421The Q.or_ class method combines a bunch of Q objects and keyword arguments
     422without all the cloning that occurs using |.
     423>>> Number.objects.filter(Q.or_(Q(num__gt=7) & Q(num__lt=12), Q(num__lt=4)))
     424[<Number: 8>]
     425>>> Number.objects.filter(Q.or_(Q(num=4), Q(num=8), Q(num=12)))
     426[<Number: 4>, <Number: 8>, <Number: 12>]
     427>>> Number.objects.filter(Q.or_(Q(num=4), Q(num=8), num=12))
     428[<Number: 4>, <Number: 8>, <Number: 12>]
     429>>> Author.objects.filter(Q.or_(name='a3', item__name='one'))
     430[<Author: a1>, <Author: a3>]
     431>>> Author.objects.filter(Q.or_(Q(name='a3'), Q(item__name='one')))
     432[<Author: a1>, <Author: a3>]
     433>>> Author.objects.filter(Q.or_(Q(name='a3'), item__name='one'))
     434[<Author: a1>, <Author: a3>]
     435
    421436Bug #7872
    422437Another variation on the disjunctive filtering theme.
    423438
Back to Top