2017-09-20 50 views
1

計數我有以下工作代碼:Django的過濾基於相關模型

houses_of_agency = House.objects.filter(agency_id=90) 
area_list = AreaHouse.objects.filter(house__in=houses_of_agency).values('area') 
area_ids = Area.objects.filter(area_id__in=area_list).values_list('area_id', flat=True) 

返回與area_ids列表的查詢集。我想進一步過濾,以便只有屬於該代理機構的房屋超過100間的情況下才能獲得area_ids。

我嘗試了以下調整:

houses_of_agency = House.objects.filter(agency_id=90) 
area_list = AreaHouse.objects.filter(house__in=houses_of_agency).annotate(num_houses=Count('house_id')).filter(num_houses__gte=100).values('area') 
area_ids = Area.objects.filter(area_id__in=area_list).values_list('area_id', flat=True) 

但它返回一個空的查詢集。

我的模型(簡體)是這樣的:

class House(TimeStampedModel): 
    house_pk = models.IntegerField() 
    agency = models.ForeignKey(Agency, on_delete=models.CASCADE) 


class AreaHouse(TimeStampedModel): 
    area = models.ForeignKey(Area, on_delete=models.CASCADE) 
    house = models.ForeignKey(House, on_delete=models.CASCADE) 


class Area(TimeStampedModel): 
    area_id = models.IntegerField(primary_key=True) 
    parent = models.ForeignKey('self', null=True) 
    name = models.CharField(null=True, max_length=30) 

編輯:我使用MySQL數據庫後端。

回答

2

您查詢agency_id只需一個下劃線。我在下面更正了您的查詢。另外,在Django中,使用pk而不是id更常見,但行爲相同。此外,不需要三個單獨的查詢,因爲您可以將所有內容合併爲一個。

另請注意,您的字段area_idhouse_pk是不必要的,django會自動創建可通過modelname__pk訪問的主鍵字段。

# note how i inlined your first query in the .filter() call 
area_list = AreaHouse.objects \ 
      .filter(house__agency__pk=90) \ 
      .annotate(num_houses=Count('house')) \ # <- 'house' 
      .filter(num_houses__gte=100) \ 
      .values('area') 

# note the double underscore 
area_ids = Area.objects.filter(area__in=area_list)\ 
         .values_list('area__pk', flat=True) 

如果您不需要中間結果,您可以進一步簡化。這裏有兩種查詢組合:

area_ids = AreaHouse.objects \ 
      .filter(house__agency__pk=90) \ 
      .annotate(num_houses=Count('house')) \ 
      .filter(num_houses__gte=100) \ 
      .values_list('area__pk', flat=True) 

最後,你似乎在你的模型中手動定義一個多一對多的關係(通過AreaHouse)。有更好的方法,請閱讀django docs

+0

其實它似乎工作。 num_houses始終爲1,因此不會給出該區域的實際房屋數量。 – Wessi

+0

那麼它的工作呢? – olieidel

+0

這是一個錯字。它不起作用。 num_houses等於1,並沒有給出該地區房屋的實際數量 – Wessi