You can use a raw() sql query to utilize postgis order_by operators:
<-> which gets the nearest neighbor using the centers of the bounding boxes to calculate the inter-object distances.
<#> which gets the nearest neighbor using the bounding boxes themselves to calculate the inter-object distances.
In your case the one you want seems to be the <-> operator, thus the raw query:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
EDIT due to own derpiness: You can omit the [:k] to add LIMIT 1 on the raw SQL query. (Don't use both as I did!)
In the process of answering your other question: How efficient is it to order by distance (entire table) in geodjango ,another solution maybe possible:
By enabling spatial indexing and narrowing down your query through logical constrains (as explained in my answer of the above -linked question) you can achieve a pretty fast KNN query as follows:
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]