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):
|
| 168 | 168 | obj.negate() |
| 169 | 169 | return obj |
| 170 | 170 | |
| | 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 | |
| 171 | 183 | class DeferredAttribute(object): |
| 172 | 184 | """ |
| 173 | 185 | A wrapper for a deferred-loading field. When the value is read from this |
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::
|
| 692 | 692 | |
| 693 | 693 | ... would not be valid. |
| 694 | 694 | |
| | 695 | If you want to "OR" together a lot of arguments at once, it's more efficient to |
| | 696 | use ``Q.or_``. ``Q.or_`` is a class method that takes any number of Q objects |
| | 697 | and keyword arguments and combines them with ``OR``, returning a new ``Q`` |
| | 698 | object. As mentioned above, all ``Q`` objects must come before any keyword |
| | 699 | arguments. |
| | 700 | |
| | 701 | The 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 | |
| 695 | 711 | .. seealso:: |
| 696 | 712 | |
| 697 | 713 | The `OR lookups examples`_ in the Django unit tests show some possible uses |
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
index 43c8437..455334b 100644
|
a
|
b
|
constraints.
|
| 418 | 418 | >>> Number.objects.filter(Q(num__gt=7) & Q(num__lt=12) | Q(num__lt=4)) |
| 419 | 419 | [<Number: 8>] |
| 420 | 420 | |
| | 421 | The Q.or_ class method combines a bunch of Q objects and keyword arguments |
| | 422 | without 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 | |
| 421 | 436 | Bug #7872 |
| 422 | 437 | Another variation on the disjunctive filtering theme. |
| 423 | 438 | |