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 | |