Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 5689)
+++ django/db/models/query.py	(working copy)
@@ -752,6 +752,9 @@
     def __or__(self, other):
         return QOr(self, other)
 
+    def __invert__(self):
+        return QNot(self)
+
     def get_sql(self, opts):
         return parse_lookup(self.kwargs.items(), opts)
 
@@ -761,6 +764,10 @@
         "Creates a negation of the q object passed in."
         self.q = q
 
+    def __invert__(self):
+        "Returns the inner, non-negated q object"
+        return self.q
+
     def get_sql(self, opts):
         try:
             joins, where, params = self.q.get_sql(opts)
Index: tests/modeltests/or_lookups/models.py
===================================================================
--- tests/modeltests/or_lookups/models.py	(revision 5689)
+++ tests/modeltests/or_lookups/models.py	(working copy)
@@ -92,6 +92,17 @@
 >>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello')
 [<Article: Hello and goodbye>]
 
+# Q objects can be negated (NOT)
+>>> 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>
Index: docs/db-api.txt
===================================================================
--- docs/db-api.txt	(revision 5689)
+++ docs/db-api.txt	(working copy)
@@ -1411,6 +1411,11 @@
 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 ``OR``
+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
