python - Django按最小距离排序到点列表
问题描述
我想获取在给定距离内至少到许多提供位置之一的所有作业的查询集,按最小距离对它们进行排序,并且不显示重复的作业。
from django.db import models
from cities.models import City
class Job(models.Model):
title = models.CharField(max_length=255)
cities = models.ManyToManyField(City)
如果只有一点,我可以这样做:
from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import Point
point = Point(x, y, srid=4326)
Job.objects.filter(cities__location__dwithin=(point, dist)) \
.annotate(distance=Distance("cities__location", point) \
.order_by('distance')
但是当我有很多点时,我为过滤器构建了一个 Q 表达式,但不确定一种干净的方式来注释作业到所有点的最小距离
query = Q()
for point in points:
query |= Q(cities__location__dwithin=(point, dist))
Job.objects.filter(query).annotate(distance=Min(...)).order_by('distance')
仅供参考,使用带有 PostGIS 扩展的 postgres 12.1
解决方案
query = Q()
distances = []
for point in points:
query |= Q(cities__location__dwithin=(point, dist))
distances.append(Distance("cities__location", point))
# LEAST requires 2 or more expressions, MIN works for single expression
if len(distances) == 1:
MIN_FUNC = Min
else:
MIN_FUNC = Least
Job.objects.filter(query).annotate(distance=MIN_FUNC(*distances)).order_by('distance')
MIN
是一个聚合函数,它采用单个表达式,例如列名,并将多个输入减少为单个输出值LEAST
是一个条件表达式,它通过从任意数量的表达式列表中选择最小值来发挥作用
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#min https://docs.djangoproject.com/en/3.0/ref/models/database-functions/#least
推荐阅读
- angular - 角度 ng 更新不起作用 - 保存代理的位置超时?
- python-3.x - 为什么 int 数据类型的大小比 python 中的 float 大?
- r - 选择以()结尾并包含主列 R 的列
- javascript - 将字符串添加到 textarea 元素中的新行
- python - 如何在python中获取unicode的十六进制部分?
- c# - 基于 DB 中的更新的 C# 更新应用程序
- python - 使用 Python 提取嵌套括号中的句子
- sql - 对连接表 sq 中的行求和
- c++ - 当我尝试将 char 输入到 int 时,为什么文件指针会卡住?
- sql - 将 Group by 中的字符串转换为 True / False