Geo Django Subclassing Queryset - PullRequest
       7

Geo Django Subclassing Queryset

0 голосов
/ 12 августа 2011

Я использую GeoDjango для поиска групп локаций разных типов.Например, модели House и Appartment являются подклассами Location.

Используя приведенный ниже набор запросов подклассов, я могу сделать что-то вроде Location.objects.all () и вернуть его мне [<House: myhouse>, <House: yourhouse>, <Appartment: myappartment>], что и является моим желанием.

Однако я также хочу определить расстояние до каждого места.Обычно без Queryset Subclassing код из приложения 2 возвращает для меня расстояния от заданной точки до каждого местоположения .... [ (<Location: Location object>, Distance(m=866.092847284))]

Однако, если я пытаюсь найти расстояния с помощью Querysets подклассов, Я получаю ошибку, такую ​​как:

AttributeError: у объекта 'Дом' нет атрибута 'расстояние'

Знаете ли вы, как я могу сохранить возможность возврата набора запросовобъектов подкласса еще есть свойство расстояния доступны на объектах подкласса?Любой совет приветствуется.

Приложение 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()

Приложение 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

Ответы [ 2 ]

0 голосов
/ 23 октября 2012

Вы должны переназначить менеджера во всех подклассах.

Из документации Django:

Руководители, определенные в неабстрактных базовых классах, не наследуются дочерними классами. Если вы хотите повторно использовать менеджер из неабстрактной базы, переопределите его явно в дочернем классе. Менеджеры такого рода, скорее всего, будут довольно специфичны для класса, в котором они определены, поэтому их наследование часто может привести к неожиданным результатам (особенно в том, что касается менеджера по умолчанию). Поэтому они не передаются в дочерние классы.

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

0 голосов
/ 18 марта 2012

Я занят, пытаясь решить этот вопрос.Как насчет этого:

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()

А остальные могут следовать из этого DjangoSnippet .

...