Index: django/contrib/gis/db/models/sql/where.py
===================================================================
--- django/contrib/gis/db/models/sql/where.py	(revision 9805)
+++ django/contrib/gis/db/models/sql/where.py	(working copy)
@@ -1,7 +1,10 @@
 import datetime
+from django.db import connection
 from django.db.models.fields import Field
+from django.db.models.sql.expressions import SQLEvaluator
 from django.db.models.sql.where import WhereNode
 from django.contrib.gis.db.backend import get_geo_where_clause, SpatialBackend
+qn = connection.ops.quote_name
 
 class GeoAnnotation(object):
     """
@@ -37,10 +40,17 @@
             # Not a geographic field, so call `WhereNode.add`.
             return super(GeoWhereNode, self).add(data, connector)
         else:
-            # `GeometryField.get_db_prep_lookup` returns a where clause
-            # substitution array in addition to the parameters.
-            where, params = field.get_db_prep_lookup(lookup_type, value)
 
+            if isinstance(value, SQLEvaluator):
+                # If an expression is used, we are getting a database column so 
+                # we we don't send to get_db_prep_lookup.
+                where =  ['%s.%s' % tuple(map(qn, value.cols[value.expression]))]
+                params = ()
+            else:
+                # `GeometryField.get_db_prep_lookup` returns a where clause
+                # substitution array in addition to the parameters.
+                where, params = field.get_db_prep_lookup(lookup_type, value)
+
             # The annotation will be a `GeoAnnotation` object that
             # will contain the necessary geometry field metadata for
             # the `get_geo_where_clause` to construct the appropriate
Index: django/contrib/gis/tests/relatedapp/tests.py
===================================================================
--- django/contrib/gis/tests/relatedapp/tests.py	(revision 9805)
+++ django/contrib/gis/tests/relatedapp/tests.py	(working copy)
@@ -1,8 +1,9 @@
 import os, unittest
-from django.contrib.gis.geos import *
+from django.contrib.gis.db.models import F, Extent, Union
+from django.contrib.gis.geos import GEOSGeometry, Point
 from django.contrib.gis.tests.utils import no_mysql, postgis
 from django.conf import settings
-from models import City, Location, DirectoryEntry
+from models import City, Location, DirectoryEntry, Parcel
 
 cities = (('Aurora', 'TX', -97.516111, 33.058333),
           ('Roswell', 'NM', -104.528056, 33.387222),
@@ -39,22 +40,14 @@
         # US Survey Feet (thus a tolerance of 0 implies error w/in 1 survey foot).
         if postgis:
             tol = 3
-            nqueries = 4 # +1 for `postgis_lib_version`
         else:
             tol = 0
-            nqueries = 3
             
         def check_pnt(ref, pnt):
             self.assertAlmostEqual(ref.x, pnt.x, tol)
             self.assertAlmostEqual(ref.y, pnt.y, tol)
             self.assertEqual(ref.srid, pnt.srid)
 
-        # Turning on debug so we can manually verify the number of SQL queries issued.
-        # DISABLED: the number of queries count testing mechanism is way too brittle.
-        #dbg = settings.DEBUG
-        #settings.DEBUG = True
-        from django.db import connection
-
         # Each city transformed to the SRID of their state plane coordinate system.
         transformed = (('Kecksburg', 2272, 'POINT(1490553.98959621 314792.131023984)'),
                        ('Roswell', 2257, 'POINT(481902.189077221 868477.766629735)'),
@@ -65,36 +58,62 @@
             # Doing this implicitly sets `select_related` select the location.
             qs = list(City.objects.filter(name=name).transform(srid, field_name='location__point'))
             check_pnt(GEOSGeometry(wkt, srid), qs[0].location.point) 
-        #settings.DEBUG= dbg
 
-        # Verifying the number of issued SQL queries.
-        #self.assertEqual(nqueries, len(connection.queries))
-
     @no_mysql
     def test04_related_aggregate(self):
         "Testing the `extent` and `unionagg` GeoQuerySet aggregates on related geographic models."
-        if postgis:
-            # One for all locations, one that excludes Roswell.
-            all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
-            txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
-            e1 = City.objects.extent(field_name='location__point')
-            e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
-            for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
-                for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val)
 
+        # This combines the Extent and Union aggregates into one query
+        aggs = City.objects.aggregate(Extent('location__point'), Union('location__point'))
+
+        # One for all locations, one that excludes Roswell.
+        all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
+        txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
+        e1 = City.objects.extent(field_name='location__point')
+        e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
+        e3 = aggs['location__point__extent']
+
+        for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
+            for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val)
+
         # The second union is for a query that has something in the WHERE clause.
         ref_u1 = GEOSGeometry('MULTIPOINT(-104.528056 33.387222,-97.516111 33.058333,-79.460734 40.18476)', 4326)
         ref_u2 = GEOSGeometry('MULTIPOINT(-97.516111 33.058333,-79.460734 40.18476)', 4326)
         u1 = City.objects.unionagg(field_name='location__point')
         u2 = City.objects.exclude(name='Roswell').unionagg(field_name='location__point')
+        u3 = aggs['location__point__union']
+
         self.assertEqual(ref_u1, u1)
         self.assertEqual(ref_u2, u2)
+        self.assertEqual(ref_u1, u3)
         
     def test05_select_related_fk_to_subclass(self):
         "Testing that calling select_related on a query over a model with an FK to a model subclass works"
         # Regression test for #9752.
         l = list(DirectoryEntry.objects.all().select_related())
 
+    def test6_f_expressions(self):
+        "Testing F() expressions on Geometry fields."
+        # Constructing a dummy parcel border and getting the City FK
+        p1_border = GEOSGeometry('POLYGON((-97.501205 33.052520,-97.501205 33.052576,-97.501150 33.052576,-97.501150 33.052520,-97.501205 33.052520))')
+        p1_city = City.objects.get(name='Aurora')
+        
+        # First parcel has incorrect center point that is equal to the City point.
+        p1 = Parcel.objects.create(name='P1', city=p1_city, center=p1_city.location.point, border=p1_border)
+        p2 = Parcel.objects.create(name='P2', city=p1_city, center=p1_border.centroid, border=p1_border)
+
+        # Should return the second Parcel, which has the center within the
+        # border.
+        qs = Parcel.objects.filter(center__within=F('border'))
+        self.assertEqual(1, len(qs))
+        self.assertEqual('P2', qs[0].name)
+
+        # Should return the first Parcel, which has the center point equal
+        # to the point in the City ForeignKey.
+        qs = Parcel.objects.filter(center=F('city__location__point'))
+        self.assertEqual(1, len(qs))
+        self.assertEqual('P1', qs[0].name)
+
     # TODO: Related tests for KML, GML, and distance lookups.
         
 def suite():
Index: django/contrib/gis/tests/relatedapp/models.py
===================================================================
--- django/contrib/gis/tests/relatedapp/models.py	(revision 9805)
+++ django/contrib/gis/tests/relatedapp/models.py	(working copy)
@@ -20,3 +20,11 @@
     listing_text = models.CharField(max_length=50)
     location = models.ForeignKey(AugmentedLocation)
     objects = models.GeoManager()
+
+class Parcel(models.Model):
+    name = models.CharField(max_length=30)
+    city = models.ForeignKey(City)
+    center = models.PointField()
+    border = models.PolygonField()
+    objects = models.GeoManager()
+    def __unicode__(self): return self.name
