문제

거리 논리를 사용합니다 이렇게 게시됩니다, 나는이 코드를 사용하여 적절하게 여겨지는 객체 세트를 돌려 받고 있습니다.

class LocationManager(models.Manager):
    def nearby_locations(self, latitude, longitude, radius, max_results=100, use_miles=True):
        if use_miles:
            distance_unit = 3959
        else:
            distance_unit = 6371

        from django.db import connection, transaction
        cursor = connection.cursor()

        sql = """SELECT id, (%f * acos( cos( radians(%f) ) * cos( radians( latitude ) ) *
        cos( radians( longitude ) - radians(%f) ) + sin( radians(%f) ) * sin( radians( latitude ) ) ) )
        AS distance FROM locations_location HAVING distance < %d
        ORDER BY distance LIMIT 0 , %d;""" % (distance_unit, latitude, longitude, latitude, int(radius), max_results)
        cursor.execute(sql)
        ids = [row[0] for row in cursor.fetchall()]

        return self.filter(id__in=ids)

문제는 목록/ 쿼리 세트를 거리 값으로 정렬하는 방법을 알 수 없다는 것입니다. 성능 이유를 위해 추가 () 메소드 호출 로이 작업을 수행하고 싶지 않습니다 (데이터베이스의 각 잠재적 위치에 대한 하나의 쿼리 대 한 쿼리). 몇 가지 질문 :

  1. 내 목록을 멀리서 어떻게 정렬 할 수 있습니까? 내 모델에서 정의한 기본 정렬을 제거하고 "order_by ()"를 사용하더라도 여전히 다른 것에 의해 분류되고 있습니다 (ID, I Believe).
  2. 성능에 대해 잘못되었고 Django는 쿼리를 최적화하므로 대신 extra ()를 사용해야합니까?
  3. 이것이 완전히 잘못된 방법입니까? 나는 Putz처럼 이것을 핸드 롤링하는 대신 Geo 라이브러리를 사용해야합니까?
도움이 되었습니까?

해결책

귀하의 질문을 역순으로 받으려면 :

RE 3) 예, 지리 공간 데이터를 사용하는 경우 Postgis와 Geodjango를 반드시 활용해야합니다. 그것은 단지 어리석지 않습니다.

re 2) .extra ()를 사용하여 Django 가이 쿼리를 할 수 있다고 생각하지 않습니다. 이 티켓), 그러나 Django 1.2의 새로운 .raw () 메소드의 훌륭한 후보입니다 (아래 참조).

Re 1) 첫 번째 쿼리에서 ID 목록을 얻은 다음 "in"쿼리를 사용하여 해당 ID에 해당하는 객체의 쿼리 세트를 가져옵니다. 두 번째 쿼리는 첫 번째 쿼리에서 계산 된 거리에 액세스 할 수 없습니다. 그것은 단지 ID 목록을 가져 오는 것입니다 (그리고 해당 ID를 제공하는 순서도 신경 쓰지 않습니다).

가능한 솔루션 (이 모든 것을 버리고 Geodjango를 사용하지 않음) :

  1. Django 1.2 베타로 업그레이드하고 사용하십시오 새로운 .raw () 메소드. 이를 통해 Django는 원시 SQL 쿼리의 결과를 지능적으로 해석하고 실제 모델 객체의 쿼리 세트로 전환 할 수 있습니다. 현재 두 쿼리를 하나로 줄이고 SQL로 지정된 순서를 보존합니다. 업그레이드를 할 수있는 최선의 옵션입니다.

  2. Django Queryset 또는 Django 모델 객체를 전혀 구조화하지 마십시오. 필요한 모든 필드를 RAW SQL SELECT에 추가 한 다음 커서에서 직접 해당 행을 사용하십시오. 나중에 모델 방법 등이 필요한 경우 옵션이 아닐 수도 있습니다.

  3. Python Code에서 세 번째 단계를 수행하여 쿼리 세트를 반복하고 첫 번째 쿼리에서 돌아온 IDS 목록과 동일한 순서로 Python 목록을 구성합니다. 쿼리 세트 대신 해당 목록을 반환하십시오. 라인을 더 이상 필터링 해야하는 경우 작동하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top