2016-05-22 72 views
8

Mam następujący model:sortować według szerokości geograficznej w geodjango

class Stop(models.Model): 
    name = models.CharField(max_length=50) 
    point = models.PointField() 
    objects = models.GeoManager() 

Chcę uporządkować moje przystanki z północy na południe. Jak mam to zrobic? Stop.objects.order_by('point') sortuje je od zachodu na wschód.

dzięki.

To mój pełny model:

from django.contrib.gis.db import models 
from django.core.urlresolvers import reverse 

class Stop(models.Model): 
    gtfs_stop_id = models.IntegerField(db_index=True, unique=True) 
    name = models.CharField(max_length=50) 
    point = models.PointField() 
    parkings = models.GeometryCollectionField(null=True, blank=True) 
    objects = models.GeoManager() 

    def get_absolute_url(self): 
     return reverse('core:stop', args=(self.id,)) 

    def __str__(self): 
     return self.name 
+0

Zawsze można zrobić 'Stop.objects.order_by ('point__x')/Stop.objects.order_by ('- point__x')' 'albo \t Stop.objects.order_by ('point__y')/Stop .objects.order_by ('- point__y') ' – trinchet

+0

dziękuję, ale to daje błąd: FieldError: Nie można rozwiązać słowa kluczowego" x "w polu. Dołącz do "punktu" nie jest dozwolone. – eran

Odpowiedz

4

Ponieważ pole punktem jest geometria i geografii nie masz szczęście.

from django.db.models import F, Func 
Stop.objects.annotate(lat=Func('point',function='ST_X')).order_by('lat') 

Używam ST_X tutaj zamiast ST_Y ponieważ PostGIS najlepszy z geodjango baz konwencja jest przechowywanie lng,lat

Jeśli Twój pola punktem była geografia powyższe wywołanie funkcji nie będzie pracował, bo ST_X i ST_Y są dostępne tylko w polach geometrii. Aby móc korzystać z tych funkcji, pola geografii muszą zostać przeniesione do geometrii.

+0

Nie jestem pewien dlaczego, ale to dało mi błąd. W końcu do tego doszłam. Stop.objects.all(). Extra (select = {'lat': 'ST_X (point)'}). Order_by ('- lat') – eran

+0

Przepraszam, widzę to teraz. W mojej odpowiedzi użyłem "lokalizacji" zamiast "punktu". – e4c5

+0

Zaktualizowałem moją odpowiedź. Sprawdź, czy działa teraz, jeśli nie, opublikuj błąd i spróbuj uniknąć użycia dodatkowych. – e4c5

0

Wpadłem na ten sam TypeError: nieprawidłowy typ wejścia geometrii: zgłoszony przez Erana, a ja w rzeczywistości używałem PointField. Rozwiązałem problem, dodając wyrażenie ExpressionWrapper, aby poinformować Django, jakiego typu danych wyjściowych oczekiwać (zmienną zamiast punktu).

Ponadto, w PostGIS, aby uzyskać szerokość geograficzną, należy użyć ST_Y.

from django.db.models import FloatField, ExpressionWrapper, Func 
Stop.objects.all().annotate(lat=ExpressionWrapper(Func('point', function='ST_Y'), output_field=FloatField())).order_by('lat')