2

我在我的一个模型上运行了一堆过滤器。具体来说,在我的一种观点中,我正在做这样的事情:

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)。

但是我正在处理查询集,而不是简单的列表,那么我该怎么做呢?

4

4 回答 4

1

问题的根源是您试图混合在数据库中完成的 sql 过滤器和一个 python 过滤器,一旦记录从数据库中具体化就完成了。如果不从数据库中获取项目然后在此基础上进行过滤,您将无法做到这一点。

你不能,通过你的 python 函数来做到这一点,但你可以通过 geodjango 做到这一点:

https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-queries

cites = cities.filter(distance_lt=101)

会给你你想要的

于 2013-06-18T07:23:55.207 回答
1

您正在尝试将 Python 方法与数据库查询混合使用,这是不可能的。要么编写 SQL 来执行距离计算(快),要么获取每一行并调用你的方法(慢)。Django 过滤器只是将参数转换为 SQL WHERE 子句,所以如果不能用 SQL 表达,可能无法用过滤器表达。

于 2013-06-15T00:12:18.560 回答
0

在我看来,您应该使用Queryset 对象,并在自定义管理器中定义复杂的过滤器方法。

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)
于 2013-06-15T10:10:11.167 回答
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”的点字段。

于 2013-06-15T00:16:44.220 回答