2017-04-23 88 views
1

我的公司(很多一對多ServiceCompany之間)提供服務的遞歸查詢。爲了構建我的服務,我使用了一個使用Django多對多字段的樹狀結構。所以,一個服務可以包含多個其他服務。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) 

回答

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

+0

這很好,非常感謝!我有一個遞歸解決方案,但這種廣度優先搜索是一種更可讀的方法。 –

+0

使用這種方法,您需要小心不要在服務圖中引入任何循環,否則這將在無限循環中運行。 – knbk

0

我忘了提,我需要一個QuerySet的返回值,所以我修改@Özgür的公司多方位的回答了一下。以防萬一某人也需要這個:

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) 

編輯:我也加了一個檢查潛在的循環。