Du kan använda en rå ()
sql-fråga för att använda postgis order_by
operatörer:
-
<->
som får närmaste granne med hjälp av mitten av begränsningsrutorna för att beräkna avstånden mellan objekt. -
<#>
som får närmaste granne att använda själva begränsningsrutorna för att beräkna avstånden mellan objekt.
I ditt fall verkar den du vill ha vara
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
REDIGERA på grund av egen hudkänsla: Du kan utelämna [:k]
för att lägga till LIMIT 1
på den råa SQL-frågan. (Använd inte båda som jag gjorde!)
Håller på att svara på din andra fråga:Hur effektivt är det att beställa efter avstånd (hela tabellen) i geodjango ,en annan lösning kanske är möjlig:
Genom att aktivera spatial indexering
och begränsa din fråga genom logiska begränsningar (som förklarat i mitt svar
av den ovan länkade frågan) kan du uppnå en ganska snabb KNN fråga enligt följande:
current_location = me.location
people = People.objects.filter(
location__dwithin=(current_location, D(km=50))
).annotate(
distance=Distance('location', current_location)
).order_by('distance')[:k]