diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 9b0f495..8b50ce0 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -912,6 +912,9 @@ class BaseDatabaseOperations(object):
         can vary between backends (e.g., Oracle with %% and &) and between
         subexpression types (e.g., date expressions)
         """
+        if connector == 'NOT':
+            assert len(sub_expressions) == 1
+            return 'NOT (%s)' % sub_expressions[0]
         conn = ' %s ' % connector
         return conn.join(sub_expressions)
 
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 639ef6e..972440b 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -18,6 +18,17 @@ class ExpressionNode(tree.Node):
     AND = '&'
     OR = '|'
 
+    # Unary operator (needs special attention in combine_expression)
+    NOT = 'NOT'
+
+    # Comparison operators
+    EQ = '='
+    GE = '>='
+    GT = '>'
+    LE = '<='
+    LT = '<'
+    NE = '<>'
+
     def __init__(self, children=None, connector=None, negated=False):
         if children is not None and len(children) > 1 and connector is None:
             raise TypeError('You have to specify a connector.')
@@ -93,6 +104,32 @@ class ExpressionNode(tree.Node):
     def __ror__(self, other):
         return self._combine(other, self.OR, True)
 
+    def __invert__(self):
+        obj = ExpressionNode([self], connector=self.NOT, negated=True)
+        return obj
+
+    def __eq__(self, other):
+        return self._combine(other, self.EQ, False)
+
+    def __ge__(self, other):
+        return self._combine(other, self.GE, False)
+
+    def __gt__(self, other):
+        return self._combine(other, self.GT, False)
+
+    def __le__(self, other):
+        return self._combine(other, self.LE, False)
+
+    def __lt__(self, other):
+        return self._combine(other, self.LT, False)
+
+    def __ne__(self, other):
+        return self._combine(other, self.NE, False)
+
+    def __bool__(self):
+        raise TypeError('Boolean operators should be avoided. Use bitwise operators.')
+    __nonzero__ = __bool__
+
     def prepare_database_save(self, unused):
         return self
 
diff --git a/django/utils/tree.py b/django/utils/tree.py
index 717181d..090e5c9 100644
--- a/django/utils/tree.py
+++ b/django/utils/tree.py
@@ -88,8 +88,11 @@ class Node(object):
         Otherwise, the whole tree is pushed down one level and a new root
         connector is created, connecting the existing tree and the new node.
         """
-        if node in self.children and conn_type == self.connector:
-            return
+        # Using for loop with 'is' instead of 'if node in children' so node
+        # __eq__ method doesn't get called
+        for child in self.children:
+            if node is child and conn_type == self.connector:
+                return
         if len(self.children) < 2:
             self.connector = conn_type
         if self.connector == conn_type:
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index 528a44c..6d37620 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -129,6 +129,10 @@ Django 1.5 also includes several smaller improvements worth noting:
   configuration duplication. More information can be found in the
   :func:`~django.contrib.auth.decorators.login_required` documentation.
 
+* The :class:`~django.db.models.expressions.ExpressionNode` object now supports
+  comparison operations and inversion, expanding the types of expressions that
+  can be passed to the database.
+
 Backwards incompatible changes in 1.5
 =====================================
 
diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt
index dd16065..9a2544b 100644
--- a/docs/topics/db/queries.txt
+++ b/docs/topics/db/queries.txt
@@ -990,6 +990,14 @@ a join with an ``F()`` object, a ``FieldError`` will be raised::
     # THIS WILL RAISE A FieldError
     >>> Entry.objects.update(headline=F('blog__name'))
 
+.. versionadded:: 1.5
+
+Django also supports the comparison operators ``==``, ``!=``, ``<=``, ``<``,
+``>``, ``>=`` and the bitwise negation operator ``~`` (boolean ``not`` operator
+will raise ``TypeError``)::
+
+    >>> Entry.objects.update(is_heavily_quoted=~(F('n_pingbacks') < 100))
+
 .. _topics-db-queries-related:
 
 Related objects
diff --git a/tests/modeltests/expressions/models.py b/tests/modeltests/expressions/models.py
index f592a0e..15f0d24 100644
--- a/tests/modeltests/expressions/models.py
+++ b/tests/modeltests/expressions/models.py
@@ -27,6 +27,8 @@ class Company(models.Model):
         Employee,
         related_name='company_point_of_contact_set',
         null=True)
+    is_large = models.BooleanField(
+        blank=True)
 
     def __str__(self):
         return self.name
diff --git a/tests/modeltests/expressions/tests.py b/tests/modeltests/expressions/tests.py
index 99eb07e..66407c7 100644
--- a/tests/modeltests/expressions/tests.py
+++ b/tests/modeltests/expressions/tests.py
@@ -11,22 +11,22 @@ from .models import Company, Employee
 class ExpressionsTests(TestCase):
     def test_filter(self):
         Company.objects.create(
-            name="Example Inc.", num_employees=2300, num_chairs=5,
+            name="Example Inc.", num_employees=2300, num_chairs=5, is_large=False,
             ceo=Employee.objects.create(firstname="Joe", lastname="Smith")
         )
         Company.objects.create(
-            name="Foobar Ltd.", num_employees=3, num_chairs=4,
+            name="Foobar Ltd.", num_employees=3, num_chairs=4, is_large=False,
             ceo=Employee.objects.create(firstname="Frank", lastname="Meyer")
         )
         Company.objects.create(
-            name="Test GmbH", num_employees=32, num_chairs=1,
+            name="Test GmbH", num_employees=32, num_chairs=1, is_large=False,
             ceo=Employee.objects.create(firstname="Max", lastname="Mustermann")
         )
 
         company_query = Company.objects.values(
-            "name", "num_employees", "num_chairs"
+            "name", "num_employees", "num_chairs", "is_large"
         ).order_by(
-            "name", "num_employees", "num_chairs"
+            "name", "num_employees", "num_chairs", "is_large"
         )
 
         # We can filter for companies where the number of employees is greater
@@ -37,11 +37,13 @@ class ExpressionsTests(TestCase):
                     "num_chairs": 5,
                     "name": "Example Inc.",
                     "num_employees": 2300,
+                    "is_large": False
                 },
                 {
                     "num_chairs": 1,
                     "name": "Test GmbH",
-                    "num_employees": 32
+                    "num_employees": 32,
+                    "is_large": False
                 },
             ],
             lambda o: o
@@ -55,17 +57,20 @@ class ExpressionsTests(TestCase):
                 {
                     "num_chairs": 2300,
                     "name": "Example Inc.",
-                    "num_employees": 2300
+                    "num_employees": 2300,
+                    "is_large": False
                 },
                 {
                     "num_chairs": 3,
                     "name": "Foobar Ltd.",
-                    "num_employees": 3
+                    "num_employees": 3,
+                    "is_large": False
                 },
                 {
                     "num_chairs": 32,
                     "name": "Test GmbH",
-                    "num_employees": 32
+                    "num_employees": 32,
+                    "is_large": False
                 }
             ],
             lambda o: o
@@ -79,17 +84,20 @@ class ExpressionsTests(TestCase):
                 {
                     'num_chairs': 2302,
                     'name': 'Example Inc.',
-                    'num_employees': 2300
+                    'num_employees': 2300,
+                    'is_large': False
                 },
                 {
                     'num_chairs': 5,
                     'name': 'Foobar Ltd.',
-                    'num_employees': 3
+                    'num_employees': 3,
+                    'is_large': False
                 },
                 {
                     'num_chairs': 34,
                     'name': 'Test GmbH',
-                    'num_employees': 32
+                    'num_employees': 32,
+                    'is_large': False
                 }
             ],
             lambda o: o,
@@ -104,17 +112,20 @@ class ExpressionsTests(TestCase):
                 {
                     'num_chairs': 6900,
                     'name': 'Example Inc.',
-                    'num_employees': 2300
+                    'num_employees': 2300,
+                    'is_large': False
                 },
                 {
                     'num_chairs': 9,
                     'name': 'Foobar Ltd.',
-                    'num_employees': 3
+                    'num_employees': 3,
+                    'is_large': False
                 },
                 {
                     'num_chairs': 96,
                     'name': 'Test GmbH',
-                    'num_employees': 32
+                    'num_employees': 32,
+                    'is_large': False
                 }
             ],
             lambda o: o,
@@ -129,21 +140,83 @@ class ExpressionsTests(TestCase):
                 {
                     'num_chairs': 5294600,
                     'name': 'Example Inc.',
-                    'num_employees': 2300
+                    'num_employees': 2300,
+                    'is_large': False
                 },
                 {
                     'num_chairs': 15,
                     'name': 'Foobar Ltd.',
-                    'num_employees': 3
+                    'num_employees': 3,
+                    'is_large': False
                 },
                 {
                     'num_chairs': 1088,
                     'name': 'Test GmbH',
-                    'num_employees': 32
+                    'num_employees': 32,
+                    'is_large': False
                 }
             ],
             lambda o: o,
         )
+        # The comparison operators and the bitwise unary not can be used
+        # to assign to boolean fields
+        for expression in (
+            # Check boundaries
+            ~(F('num_employees') < 33),
+            ~(F('num_employees') <= 32),
+            (F('num_employees') > 2299),
+            (F('num_employees') >= 2300),
+            (F('num_employees') == 2300),
+            ((F('num_employees') + 1 != 4) & (32 != F('num_employees'))),
+            # Inverted argument order works too
+            (2299 < F('num_employees')),
+            (2300 <= F('num_employees'))
+        ):
+            # Test update by F-expression
+            company_query.update(
+                is_large=expression
+            )
+            # Compare results
+            self.assertQuerysetEqual(
+                company_query, [
+                    {
+                        'num_chairs': 5294600,
+                        'name': u'Example Inc.',
+                        'num_employees': 2300,
+                        'is_large': True
+                    },
+                    {
+                        'num_chairs': 15,
+                        'name': u'Foobar Ltd.',
+                        'num_employees': 3,
+                        'is_large': False
+                    },
+                    {
+                        'num_chairs': 1088,
+                        'name': u'Test GmbH',
+                        'num_employees': 32,
+                        'is_large': False
+                    }
+                ],
+                lambda o: o,
+            )
+            # Reset values
+            company_query.update(
+                is_large=False
+            )
+
+        # The python boolean operators should be avoided as they yield
+        # unexpected results
+        test_gmbh = Company.objects.get(name="Test GmbH")
+        def test():
+            test_gmbh.is_large = not F('is_large')
+        self.assertRaises(TypeError, test)
+        def test():
+            test_gmbh.is_large = F('is_large') and F('is_large')
+        self.assertRaises(TypeError, test)
+        def test():
+            test_gmbh.is_large = F('is_large') or F('is_large')
+        self.assertRaises(TypeError, test)
 
         # The relation of a foreign key can become copied over to an other
         # foreign key.
