私は Django プロジェクトに取り組んでおり、School テーブルの各アイテムについて、たまたま一定の距離にあるすべての病院を Web サービス経由で報告する必要があります。以下は、2 つのモデルのダミーの実装です。
class School(models.Model):
location = models.PointField(srid=4326, geography=True)
...some other fields...
objects = models.GeoManager()
class Hospital
location = models.PointField(srid=4326, geography=True)
...some other fields...
objects = models.GeoManager()
これは不自然な例であることを記録として述べておきますが、要点は次のとおりです。
- どちらのモデルも、他のモデルとの外部キー関係を持っていません (そうすべきではありません)
- 唯一の関係は距離によるものです
現在、Django Rest Framework (DRF) を使用してリクエストをレンダリングしており、Django Rest Framework (DRF) が提供するシリアライザー クラスを使用して、次の行に沿って何かを実行しています。
class SchoolSerializer(serializers.ModelSerializer):
nearby_hospitals = serializers.SerializerMethodField('get_nearby_hospitals')
class Meta:
model = School
fields = ('location', 'nearby_hospitals',)
def get_nearby_hospitals(self, obj):
geom = obj.location
try:
locations = Hospitals.objects.filter(loc__dwithin=(geom, 10000))
return HospitalSerializer(locations, many=True).data
except:
return
これは機能しますが、効率的ではありません。基本的に、DRF はすべての学校を読み込み、そこから各学校をループして get_nearby_hospitals でクエリを実行します。データベース クエリの数は、Schools 内のアイテムの数に 1 を加えた数 (Schools を取得するため) に等しくなります。
理想的には、これらの行に沿って何かを実行する Django ソリューションが必要です (明らかに、リストされているフィールド、ID 列名を衝突させるためのエイリアスなど):
SELECT * FROM schools JOIN
hospitals ON ST_DWithin(schools.location, hospitals.location, 10000)
上記のクエリは、適切な距離内にあるすべての学校と病院の交差点を生成します。これらの結果を手動でクエリセットにマージするか、より良いクエリを作成してQuerySet メソッドをSchool.objects.all()
呼び出して、求めているものを 1 回で取得することができます。raw
この問題に対するより良い、またはより多くの「Django Way」ソリューションはありますか?