web/lib/django/contrib/gis/tests/relatedapp/tests.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 import os, unittest
     1 import os, unittest
     2 from django.contrib.gis.geos import *
     2 from django.contrib.gis.geos import *
     3 from django.contrib.gis.db.backend import SpatialBackend
       
     4 from django.contrib.gis.db.models import Collect, Count, Extent, F, Union
     3 from django.contrib.gis.db.models import Collect, Count, Extent, F, Union
     5 from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_spatialite
     4 from django.contrib.gis.geometry.backend import Geometry
       
     5 from django.contrib.gis.tests.utils import mysql, oracle, postgis, spatialite, no_mysql, no_oracle, no_spatialite
     6 from django.conf import settings
     6 from django.conf import settings
     7 from models import City, Location, DirectoryEntry, Parcel, Book, Author
     7 from models import City, Location, DirectoryEntry, Parcel, Book, Author
     8 
     8 
     9 cities = (('Aurora', 'TX', -97.516111, 33.058333),
     9 cities = (('Aurora', 'TX', -97.516111, 33.058333),
    10           ('Roswell', 'NM', -104.528056, 33.387222),
    10           ('Roswell', 'NM', -104.528056, 33.387222),
    17         "Setting up for related model tests."
    17         "Setting up for related model tests."
    18         for name, state, lon, lat in cities:
    18         for name, state, lon, lat in cities:
    19             loc = Location.objects.create(point=Point(lon, lat))
    19             loc = Location.objects.create(point=Point(lon, lat))
    20             c = City.objects.create(name=name, state=state, location=loc)
    20             c = City.objects.create(name=name, state=state, location=loc)
    21 
    21 
    22     @no_oracle # TODO: Fix select_related() problems w/Oracle and pagination.
       
    23     def test02_select_related(self):
    22     def test02_select_related(self):
    24         "Testing `select_related` on geographic models (see #7126)."
    23         "Testing `select_related` on geographic models (see #7126)."
    25         qs1 = City.objects.all()
    24         qs1 = City.objects.all()
    26         qs2 = City.objects.select_related()
    25         qs2 = City.objects.select_related()
    27         qs3 = City.objects.select_related('location')
    26         qs3 = City.objects.select_related('location')
    32                 self.assertEqual(nm, c.name)
    31                 self.assertEqual(nm, c.name)
    33                 self.assertEqual(st, c.state)
    32                 self.assertEqual(st, c.state)
    34                 self.assertEqual(Point(lon, lat), c.location.point)
    33                 self.assertEqual(Point(lon, lat), c.location.point)
    35 
    34 
    36     @no_mysql
    35     @no_mysql
    37     @no_oracle # Pagination problem is implicated in this test as well.
       
    38     def test03_transform_related(self):
    36     def test03_transform_related(self):
    39         "Testing the `transform` GeoQuerySet method on related geographic models."
    37         "Testing the `transform` GeoQuerySet method on related geographic models."
    40         # All the transformations are to state plane coordinate systems using
    38         # All the transformations are to state plane coordinate systems using
    41         # US Survey Feet (thus a tolerance of 0 implies error w/in 1 survey foot).
    39         # US Survey Feet (thus a tolerance of 0 implies error w/in 1 survey foot).
    42         tol = 0
    40         tol = 0
    93         # Creating the reference union geometry depending on the spatial backend,
    91         # Creating the reference union geometry depending on the spatial backend,
    94         # as Oracle will have a different internal ordering of the component
    92         # as Oracle will have a different internal ordering of the component
    95         # geometries than PostGIS.  The second union aggregate is for a union
    93         # geometries than PostGIS.  The second union aggregate is for a union
    96         # query that includes limiting information in the WHERE clause (in other
    94         # query that includes limiting information in the WHERE clause (in other
    97         # words a `.filter()` precedes the call to `.unionagg()`).
    95         # words a `.filter()` precedes the call to `.unionagg()`).
    98         if SpatialBackend.oracle:
    96         if oracle:
    99             ref_u1 = MultiPoint(p3, p1, p2, srid=4326)
    97             ref_u1 = MultiPoint(p3, p1, p2, srid=4326)
   100             ref_u2 = MultiPoint(p3, p2, srid=4326)
    98             ref_u2 = MultiPoint(p3, p2, srid=4326)
   101         else:
    99         else:
   102             ref_u1 = MultiPoint(p1, p2, p3, srid=4326)
   100             ref_u1 = MultiPoint(p1, p2, p3, srid=4326)
   103             ref_u2 = MultiPoint(p2, p3, srid=4326)
   101             ref_u2 = MultiPoint(p2, p3, srid=4326)
   142         # border.
   140         # border.
   143         qs = Parcel.objects.filter(center1__within=F('border1'))
   141         qs = Parcel.objects.filter(center1__within=F('border1'))
   144         self.assertEqual(1, len(qs))
   142         self.assertEqual(1, len(qs))
   145         self.assertEqual('P2', qs[0].name)
   143         self.assertEqual('P2', qs[0].name)
   146 
   144 
   147         if not SpatialBackend.mysql:
   145         if not mysql:
   148             # This time center2 is in a different coordinate system and needs
   146             # This time center2 is in a different coordinate system and needs
   149             # to be wrapped in transformation SQL.
   147             # to be wrapped in transformation SQL.
   150             qs = Parcel.objects.filter(center2__within=F('border1'))
   148             qs = Parcel.objects.filter(center2__within=F('border1'))
   151             self.assertEqual(1, len(qs))
   149             self.assertEqual(1, len(qs))
   152             self.assertEqual('P2', qs[0].name)
   150             self.assertEqual('P2', qs[0].name)
   155         # to the point in the City ForeignKey.
   153         # to the point in the City ForeignKey.
   156         qs = Parcel.objects.filter(center1=F('city__location__point'))
   154         qs = Parcel.objects.filter(center1=F('city__location__point'))
   157         self.assertEqual(1, len(qs))
   155         self.assertEqual(1, len(qs))
   158         self.assertEqual('P1', qs[0].name)
   156         self.assertEqual('P1', qs[0].name)
   159 
   157 
   160         if not SpatialBackend.mysql:
   158         if not mysql:
   161             # This time the city column should be wrapped in transformation SQL.
   159             # This time the city column should be wrapped in transformation SQL.
   162             qs = Parcel.objects.filter(border2__contains=F('city__location__point'))
   160             qs = Parcel.objects.filter(border2__contains=F('city__location__point'))
   163             self.assertEqual(1, len(qs))
   161             self.assertEqual(1, len(qs))
   164             self.assertEqual('P1', qs[0].name)
   162             self.assertEqual('P1', qs[0].name)
   165 
   163 
   173         # Incrementing through each of the models, dictionaries, and tuples
   171         # Incrementing through each of the models, dictionaries, and tuples
   174         # returned by the different types of GeoQuerySets.
   172         # returned by the different types of GeoQuerySets.
   175         for m, d, t in zip(gqs, gvqs, gvlqs):
   173         for m, d, t in zip(gqs, gvqs, gvlqs):
   176             # The values should be Geometry objects and not raw strings returned
   174             # The values should be Geometry objects and not raw strings returned
   177             # by the spatial database.
   175             # by the spatial database.
   178             self.failUnless(isinstance(d['point'], SpatialBackend.Geometry))
   176             self.failUnless(isinstance(d['point'], Geometry))
   179             self.failUnless(isinstance(t[1], SpatialBackend.Geometry))
   177             self.failUnless(isinstance(t[1], Geometry))
   180             self.assertEqual(m.point, d['point'])
   178             self.assertEqual(m.point, d['point'])
   181             self.assertEqual(m.point, t[1])
   179             self.assertEqual(m.point, t[1])
   182 
   180 
   183     def test08_defer_only(self):
   181     def test08_defer_only(self):
   184         "Testing defer() and only() on Geographic models."
   182         "Testing defer() and only() on Geographic models."
   236         "Testing `Count` aggregate use with the `GeoManager` on geo-fields."
   234         "Testing `Count` aggregate use with the `GeoManager` on geo-fields."
   237         # Creating a new City, 'Fort Worth', that uses the same location
   235         # Creating a new City, 'Fort Worth', that uses the same location
   238         # as Dallas.
   236         # as Dallas.
   239         dallas = City.objects.get(name='Dallas')
   237         dallas = City.objects.get(name='Dallas')
   240         ftworth = City.objects.create(name='Fort Worth', state='TX', location=dallas.location)
   238         ftworth = City.objects.create(name='Fort Worth', state='TX', location=dallas.location)
   241         
   239 
   242         # Count annotation should be 2 for the Dallas location now.
   240         # Count annotation should be 2 for the Dallas location now.
   243         loc = Location.objects.annotate(num_cities=Count('city')).get(id=dallas.location.id)
   241         loc = Location.objects.annotate(num_cities=Count('city')).get(id=dallas.location.id)
   244         self.assertEqual(2, loc.num_cities)
   242         self.assertEqual(2, loc.num_cities)
   245 
   243 
   246     def test12b_count(self):
   244     def test12b_count(self):
   277     @no_oracle
   275     @no_oracle
   278     @no_spatialite
   276     @no_spatialite
   279     def test14_collect(self):
   277     def test14_collect(self):
   280         "Testing the `collect` GeoQuerySet method and `Collect` aggregate."
   278         "Testing the `collect` GeoQuerySet method and `Collect` aggregate."
   281         # Reference query:
   279         # Reference query:
   282         # SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN 
   280         # SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN
   283         #    "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id") 
   281         #    "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id")
   284         #    WHERE "relatedapp_city"."state" = 'TX';
   282         #    WHERE "relatedapp_city"."state" = 'TX';
   285         ref_geom = fromstr('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
   283         ref_geom = fromstr('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
   286         
   284 
   287         c1 = City.objects.filter(state='TX').collect(field_name='location__point')
   285         c1 = City.objects.filter(state='TX').collect(field_name='location__point')
   288         c2 = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect']
   286         c2 = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect']
   289 
   287 
   290         for coll in (c1, c2):
   288         for coll in (c1, c2):
   291             # Even though Dallas and Ft. Worth share same point, Collect doesn't
   289             # Even though Dallas and Ft. Worth share same point, Collect doesn't