3

場所の座標にPointFieldを使用したモデルがあります。distと呼ばれる2点間の距離を計算するMySQL関数があります。extra() "select"を使用して、クエリセットで返された各オブジェクトの距離を計算します。また、extra() "where"を使用して、特定の範囲内にあるオブジェクトをフィルタリングします。このような

query = queryset.extra(
    select={
        "distance":"dist(geomfromtext('%s'),geomfromtext('%s'))"%(loc1, loc2)
    },
    where=["1 having `distance` <= %s"%(km)]
) #simplified example

これは、結果セットをカウントしようとすると、「距離」がフィールドではないというエラーが発生することを除いて、結果の取得と読み取りに問題なく機能します。もう少し詳しく調べてみると、countはextraからの「select」を無視し、「where」のみを使用しているようです。完全なSQLクエリは次のようになりますが、次のようになります。

SELECT (dist(geomfromtext('POINT (-4.6858300000000003 36.5154300000000021)'),geomfromtext('POINT (-4.8858300000000003 36.5154300000000021)'))) AS `distance`, `testmodel`.`id`, `testmodel`.`name`, `testmodel`.`email`, (...) FROM `testmodel` WHERE 1 having `distance` <= 50.0

カウントクエリははるかに短く、dist選択部分はありません。

SELECT COUNT( `testmodel`.`id`) FROM `testmodel` WHERE 1 having `distance` <= 50.0

論理的には、「距離」が定義されていないため、MySQLはエラーを出します。カウントのための追加の選択を含める必要があることをDjangoに伝える方法はありますか?

アイデアをありがとう!

4

1 に答える 1

0

他のデータベースシステムを使用する予定がない場合は、生のクエリを使用できます。

    params = {'point1':wktpoint1, 'point2':wktpoint2}
    query = """
        SELECT
            dist(%(point1)s, %(point2)s)
        FROM
            testmodel
    ;"""
    query_set = self.raw(query, params)

また、より多くのGISサポートが必要な場合は、PostgreSQL + PostGISを評価する必要があります(車輪の再発明をしたくない場合は、独自のdist関数を作成しないでください)

DjangoはGeoDjangoを通じてGISサポートを提供します。そこに距離のような関数があります。ここでサポートを確認する必要があります

GeoDjangoを使用するには、youtモデルにフィールドを追加し、GeoManagerを使用するように指示する必要があります。その後、ジオクエリの実行を開始できます。問題はありませんcount

mysqlを使用すると、geodjangoを使用してこのようなことを行うことができます

### models.py
from django.contrib.gis.db import models
class YourModel(models.Model):
    your_geo_field=models.PolygonField()
    #your_geo_field=models.PointField()
    #your_geo_field=models.GeometryField()
    objects = models.GeoManager()

### your code
from django.contrib.gis.geos import *
from django.contrib.gis.measure import D
a_geom=fromstr('POINT(-96.876369 29.905320)', srid=4326)
distance=5
YoourModel.objects.filter(your_geo_field__distance_lt=(a_geom, D(m=distance))).count()

ここでより良い例とここでリファレンスを見ることができます

于 2012-07-04T21:11:47.517 に答える