Django递归查询非对称的多对多到同一模型

时间:2017-04-23 13:05:04

标签: django django-models many-to-many

我正在为公司提供服务(ServiceCompany之间的多对多)。为了构建我的服务,我使用Django的多对多字段来使用树状结构。因此,服务可以包含多个其他服务。

问题:如何检索公司的所有服务?使用company.services,我只获得与该公司直接相关的服务。我需要直接相关的+ included_services(以递归方式)。

class Company(models.Model):
    services = models.ManyToManyField(Service)

class Service(models.Model):
    name = models.CharField(max_length=255)
    included_services = models.ManyToManyField("self", blank=True, symmetrical=False)

2 个答案:

答案 0 :(得分:0)

我不认为你可以使用Django的ORM框架或写一个简单的原始SQL语句来做到这一点。您可能希望查看第三方库(如django-mptt),它们使您能够更有效地存储/检索以树状结构表示的模型。

但是,如果你想通过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

上述想法与在树中执行breadth-first search非常相似。

答案 1 :(得分:0)

我忘了提到我需要一个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)

编辑:我还添加了潜在循环检查。