2011-08-12 3 views
0

J'utilise GeoDjango pour rechercher un tas d'emplacements de différents types. Par exemple, les modèles House et Appartment sont des sous-classes de Location. En utilisant le Queryset de sous-classes ci-dessous, je suis capable de faire quelque chose comme Location.objects.all() et de me le renvoyer [<House: myhouse>, <House: yourhouse>, <Appartment: myappartment>], ce qui est mon désir.Geo Django Sous-classe Queryset

Cependant, je veux également déterminer la distance à chaque emplacement. Normalement, sans Subclassing queryset, le code de la pièce 2 revient pour moi les distances du point donné à chaque endroit .... [ (<Location: Location object>, Distance(m=866.092847284))]

Cependant, si j'essaie de trouver les distances en utilisant les sous-classement QuerySets, je reçois un erreur tel que:

AttributeError: objet « Maison » n'a pas d'attribut « distance »

savez-vous comment je peux préserver la capacité retourner un queryset d'objets sous-classées mais ont la propriété à distance disponible sur la sous-classe objets? Tout conseil est fort apprécié.

pièce 1:

class SubclassingQuerySet(models.query.GeoQuerySet): 
    def __getitem__(self, k): 
     result = super(SubclassingQuerySet, self).__getitem__(k) 
     if isinstance(result, models.Model) : 
      return result.as_leaf_class() 
     else : 
      return result 
    def __iter__(self): 
     for item in super(SubclassingQuerySet, self).__iter__(): 
      yield item.as_leaf_class() 

class LocationManager(models.GeoManager): 
    def get_query_set(self): 
     return SubclassingQuerySet(self.model) 

class Location(models.Model): 
    content_type = models.ForeignKey(ContentType,editable=False,null=True) 
    objects = LocationManager() 

class House(Location): 
    address = models.CharField(max_length=255, blank=True, null=True) 
    objects = LocationManager() 

class Appartment(Location): 
    address = models.CharField(max_length=255, blank=True, null=True) 
    unit = models.CharField(max_length=255, blank=True, null=True) 
    objects = LocationManager() 

Tableau 2:

from django.contrib.gis.measure import D 
from django.contrib.gis.geos import fromstr 
ref_pnt = fromstr('POINT(-87.627778 41.881944)') 

location_objs = Location.objects.filter(
     point__distance_lte=(ref_pnt, D(m=1000) 
      )).distance(ref_pnt).order_by('distance') 
[ (l, l.distance) for l in location_objs.distance(ref_pnt) ] # <--- errors out here 

Répondre

0

Je suis occupé à essayer de résoudre celui-ci à. Que diriez-vous ceci:

class QuerySetManager(models.GeoManager): 
    ''' 
    Generates a new QuerySet method and extends the original query object manager in the Model 
    ''' 
    def get_query_set(self): 
     return super(QuerySetManager, self).get_query_set() 

Et le reste peut suivre de ce DjangoSnippet.

0

Vous devez réaffecter le gestionnaire dans toutes les sous-classes.

De la documentation Django:

Managers defined on non-abstract base classes are not inherited by child classes. If you want to reuse a manager from a non-abstract base, redeclare it explicitly on the child class. These sorts of managers are likely to be fairly specific to the class they are defined on, so inheriting them can often lead to unexpected results (particularly as far as the default manager goes). Therefore, they aren't passed onto child classes.

https://docs.djangoproject.com/en/dev/topics/db/managers/#custom-managers-and-model-inheritance