1
0
mirror of https://github.com/django/django.git synced 2025-07-06 10:49:17 +00:00

queryset-refactor: Added ~ support to Q-objects. Based heavily on a patch from

Collin Grady. Refs #4858.


git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6518 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-10-15 03:32:11 +00:00
parent f74464da52
commit a3b22d9db0
3 changed files with 27 additions and 4 deletions

View File

@ -40,6 +40,9 @@ class Q(tree.Node):
def __and__(self, other):
return self._combine(other, self.AND)
def __invert__(self):
return QNot(self)
class QNot(Q):
"""
Encapsulates the negation of a Q object.
@ -50,3 +53,6 @@ class QNot(Q):
self.add(q, self.AND)
self.negate()
def __invert__(self):
return self.children[0]

View File

@ -211,11 +211,11 @@ Saving ForeignKey and ManyToManyField fields
--------------------------------------------
Updating ``ForeignKey`` fields works exactly the same way as saving a normal
field; simply assign an object of the right type to the field in question::
field; simply assign an object of the right type to the field in question::
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()
Updating a ``ManyToManyField`` works a little differently; use the ``add()``
method on the field to add a record to the relation::
@ -1563,6 +1563,12 @@ This is equivalent to the following SQL ``WHERE`` clause::
You can compose statements of arbitrary complexity by combining ``Q`` objects
with the ``&`` and ``|`` operators. You can also use parenthetical grouping.
``Q`` objects can also be negated using the ``~`` operator, allowing for
combined lookups that combine both a normal query and a negated (``NOT``)
query::
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
Each lookup function that takes keyword-arguments (e.g. ``filter()``,
``exclude()``, ``get()``) can also be passed one or more ``Q`` objects as
positional (not-named) arguments. If you provide multiple ``Q`` object

View File

@ -90,6 +90,17 @@ __test__ = {'API_TESTS':"""
>>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello')
[<Article: Hello and goodbye>]
# Q objects can be negated
>>> Article.objects.filter(Q(pk=1) | ~Q(pk=2))
[<Article: Hello>, <Article: Hello and goodbye>]
>>> Article.objects.filter(~Q(pk=1) & ~Q(pk=2))
[<Article: Hello and goodbye>]
# This allows for more complex queries than filter() and exclude() alone would
# allow
>>> Article.objects.filter(Q(pk=1) & (~Q(pk=2) | Q(pk=3)))
[<Article: Hello>]
# Try some arg queries with operations other than get_list
>>> Article.objects.get(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
<Article: Hello and goodbye>