Skip to main content
 首页 » 编程设计

python之简化 Django ORM 查询

2024年08月22日38davidwang456

这是我的好函数:

def is_serviceable(address): 
    """ 
    Checks if an address can be serviced by an Employee. 
    Returns True if address' lat-lng intersects with any of Employees' coverage. 
    If it doesn't, but address' locality is listed in world District model, 
    returns False and locality name. 
    Just returns False if nothing found. 
 
    -- address -- django-address Address object. Address should be geocoded (i.e 
    have latitude and longitude fields correctly filled) 
    """ 
    pnt = Point(address.longitude, address.latitude) 
    employee_exists = Employee.objects.filter(coverage__mpoly__intersects=pnt).exists() 
    district = District.objects.filter(mpoly__intersects=pnt).first() 
    if (employee_exists): 
        return employee_exists 
    elif district: 
        return False, district.name 
    else: 
        return False 

为了获得我想要的结果,我必须执行两个数据库查询,首先查询 Employee 表,然后查询 District 表。这似乎不是一种可扩展的方法。但是,由于Employee的coverage属性实际上是与District模型的多对多关系字段:

class Employee(models.Model): 
    coverage = models.ManyToManyField( 
        District, 
        related_name="employees", 
        verbose_name=_("assigned districts") 
        ) 
 
class District(models.Model): 
    mpoly = models.MultiPolygonField() 

...我很确定有一种方法可以将查询压缩到一个查询集中,或者,如果 Django ORM 不适合这种情况,则可以压缩到单个 SQL 语句。

不过,我不知道从哪里开始挖掘。有什么想法吗?

编辑:由于 Django 的注释功能而解决。

请您参考如下方法:

员工对象可以访问其相关的 District 对象:

x=Employee.objects.all()[0] 
print x.district_set.all()