非对称多对多对同模型上的Django递归查询
我为公司提供服务(在非对称多对多对同模型上的Django递归查询,django,django-models,many-to-many,Django,Django Models,Many To Many,我为公司提供服务(在服务和公司之间的多对多)。为了构造我的服务,我使用Django的多对多字段使用树状结构。因此,一个服务可以包含多个其他服务 问题是:如何检索公司拥有的所有服务?使用company.services,我只获得与该公司直接相关的服务。我需要直接相关的服务+包含的服务(以递归方式) 我认为使用Django的ORM框架或编写一条简单的原始SQL语句都无法做到这一点。您可能想看看这样的第三方库,它使您能够更高效地存储/检索以树状结构表示的模型 但是,如果您想通过Python实现这一点,
服务
和公司
之间的多对多)。为了构造我的服务,我使用Django的多对多字段使用树状结构。因此,一个服务可以包含多个其他服务
问题是:如何检索公司拥有的所有服务?使用company.services
,我只获得与该公司直接相关的服务。我需要直接相关的服务+包含的服务(以递归方式)
我认为使用Django的ORM框架或编写一条简单的原始
SQL
语句都无法做到这一点。您可能想看看这样的第三方库,它使您能够更高效地存储/检索以树状结构表示的模型
但是,如果您想通过Python实现这一点,您可以这样做:
def get_services(company):
services = list(company.services.all())
result = []
while services:
service = services.pop(0)
result.append(service)
services.extend(list(service.included_services.all()))
return result
上面的想法非常类似于在树中执行操作。我认为使用Django的ORM框架或编写简单的原始
SQL
语句无法做到这一点。您可能想看看这样的第三方库,它使您能够更高效地存储/检索以树状结构表示的模型
但是,如果您想通过Python实现这一点,您可以这样做:
def get_services(company):
services = list(company.services.all())
result = []
while services:
service = services.pop(0)
result.append(service)
services.extend(list(service.included_services.all()))
return result
上面的想法非常类似于在树中执行查询。我忘了提到我需要一个查询集作为返回值,所以我稍微修改了@ozgur的优秀答案。以防有人也需要:
def get_services(company):
services = list(company.services.all())
pks = []
while services:
service = services.pop(0)
if service.pk not in pks:
pks.append(service.pk)
services.extend(list(service.included_services.all()))
return Service.objects.filter(pk__in=pks)
编辑:我还添加了一个潜在循环的检查。我忘了提到我需要一个QuerySet作为返回值,所以我稍微修改了@ozgur的优秀答案。以防有人也需要:
def get_services(company):
services = list(company.services.all())
pks = []
while services:
service = services.pop(0)
if service.pk not in pks:
pks.append(service.pk)
services.extend(list(service.included_services.all()))
return Service.objects.filter(pk__in=pks)
编辑:我还添加了一个潜在循环的检查。这很好,非常感谢!我有一个递归解决方案,但这种广度优先搜索是一种更具可读性的方法。使用这种方法,您需要小心,不要在服务图中引入任何循环,否则这将在无限循环中运行。这很好,非常感谢!我有一个递归解决方案,但这种广度优先的搜索方法更具可读性。使用这种方法时,您需要小心,不要在服务图中引入任何循环,否则这将在无限循环中运行。