我在我的一个型号上运行了一堆过滤器。具体来说,我在我的一个观点中做了类似的事情:
cities = City.objects.filter(name__icontains=request.GET['name']
cities = City.objects.filter(population__gte=request.GET['lowest_population']
return cities
现在我想添加另一种不同类型的过滤器。具体来说,我想只包括那些距离特定邮政编码一定距离的城市。我已经有了相关的功能,例如:
distanceFromZipCode(city, zipCode)
# This returns 110 miles, for example
如何将django的查询集过滤与我想添加的这个额外过滤器结合起来?我知道如果城市只是一个列表,我可以使用.filter()并传入适当的lambda(例如,如果距相关邮政编码的距离<100,则返回true)。
但是我正在处理查询集,而不是简单的列表,所以我该怎么做呢?
答案 0 :(得分:2)
问题的根源在于您尝试混合在db中完成的sql过滤器和python过滤器,这是在从db实现记录后完成的。如果不从数据库中获取项目然后在其上进行过滤,则无法执行此操作。
你不能,通过你的python函数来做,但你可以通过geodjango来做到这一点:
https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-queries
cites = cities.filter(distance_lt=101)
会得到你想要的东西
答案 1 :(得分:1)
您正在尝试将Python方法与数据库查询混合使用,而这是不可能的。您可以编写SQL来执行距离计算(快速),也可以获取每一行并调用方法(慢速)。 Django过滤器只是将参数转换为SQL WHERE子句,因此如果您无法在SQL中表达它,您可能无法在过滤器中表达它。
答案 2 :(得分:0)
如果您将城市的位置存储为几何图形,则可以使用与其余过滤器链接的距离空间过滤器:
from django.contrib.gis.measure import D
zipCode = ZipCode.objects.all()[0]
cities = City.objects.filter(point__distance_lte=(zipCode.geom, D(mi=110)))
这假设您有一个ZipCode模型,其中包含每个邮政编码的几何图形,并且几何图形存储在一个名为“geom”的字段中,而您的City对象有一个名为“point”的点字段。
答案 3 :(得分:0)
在我看来,您应该使用Queryset object,并在custom manager中定义复杂的过滤方法。
from django.db import models
from django.db.models import Q
class CityManager(models.Manager):
def get_filtered_cities(self, name=None, lowest_population=None, zip_code=None):
query = Q()
if(name):
query = Q(name__icontains=name)
if(lowest_population):
query = query & Q(population__gte=lowest_population)
if(zip_code):
pass #other query object
return self.get_query_set().filter(query)