2017-02-08 210 views
0

我試圖顯示來自幾個通過QuerySet相關的模型的數據。我的最終目標是根據Site模型中sw_delivery_date的日期範圍過濾器顯示Site模型中的一些信息以及Ppack模型中的一些信息。如何顯示相關模型的相關模型中的Django數據?

這裏是我的模型:

class Site(models.Model): 
    mnemonic = models.CharField(max_length = 5) 
    site_name = models.CharField(max_length = 100) 
    assigned_tech = models.ForeignKey('Person', on_delete=models.CASCADE, null = True, blank = True) 
    hw_handoff_date = models.DateField(null = True, blank = True) 
    sw_delivery_date = models.DateField(null = True, blank = True) 
    go_live_date = models.DateField(null = True, blank = True) 
    web_url = models.CharField(max_length = 100, null = True, blank = True) 
    idp_url = models.CharField(max_length = 100, null = True, blank = True) 

    def __str__(self): 
     return '(' + self.mnemonic + ') ' + self.site_name 

class Ring(models.Model): 
    ring = models.IntegerField() 

    def __str__(self): 
     return "6." + str(self.ring) 

class Ppack(models.Model): 
    ppack = models.IntegerField() 
    ring = models.ForeignKey('Ring', on_delete=models.CASCADE) 

    def __str__(self): 
     return str(self.ring) + " pp" + str(self.ppack) 

class Code_Release(models.Model): 
    Inhouse = 'I' 
    Test = 'T' 
    Live = 'L' 
    Ring_Location_Choices = (
      (Inhouse, 'Inhouse'), 
      (Test, 'Test'), 
      (Live, 'Live'), 
          ) 

    site_id = models.ForeignKey('Site', on_delete=models.CASCADE) 
    type = models.CharField(max_length = 1, choices = Ring_Location_Choices, blank = True, null = True) 
    release = models.ForeignKey('Ppack', on_delete=models.CASCADE) 

    def __str__(self): 
     return "site:" + str(self.site_id) + ", " + self.type + " = " + str(self.release) 

如果我用下面,

today = datetime.date.today() 
future = datetime.timedelta(days=60) 
new_deliveries = Site.objects.select_related().filter(sw_delivery_date__range=[today, (today + future)]) 

我可以得到所有的滿足我的條件,但該網站的模型對象,因爲有沒有從Site到Code_Release的關係(有一對一的來自另一種方式),我無法獲得Code_Release數據。

如果我運行一個for循環,我可以遍歷從上述查詢返回的每個站點,並從Code_Release模型中選擇數據,這使我可以從Ppack和Ring模型中獲取相關數據。

site_itl = {} 
itl = {} 
for delivery in new_deliveries: 
    releases = Code_Release.objects.select_related().filter(site_id = delivery.id) 

    for rel in releases: 
     itl[rel.id] = rel.release 

    site_itl[delivery.id] = itl 

但是,這似乎對我來說過於複雜,有多個數據庫命中,並可能困難的時間解析通過模板。

基於此,我想我需要從Code_Release模型中進行選擇。這涉及到Site模型和Ppack模型(與Ring模型有關)。我一直在努力以這種方式正確地查詢/訪問數據,以實現我想要的,但我認爲這是正確的方式。

我該如何做到最好?

+0

請澄清 - 目標是檢索一組Code_Release對象?除了那些之外,你還需要什麼關係? –

+0

我希望能夠顯示以下內容: 站點名稱,sw_delivery_date,發佈信息(Ppack模型的str表示形式)和assigned_tech –

回答

0

您可以在這裏使用RelatedManager。當你聲明ForeignKey時,Django允許你訪問反向關係。具體而言,假設您有多個指向特定站點的代碼版本。您可以使用<your_model_name_lowercase>_set屬性通過站點對象訪問它們。所以你的情況:

site.code_release_set.all() 

將返回擁有所有代碼發佈對象的查詢集ForeignKey的反對site

+0

非常感謝 - 這正是我所需要的。我可以使用'site.code_release_set.get(type =「I」)。release'來獲取特定的數據(網站內部環境的發佈名稱)。 –

+0

我可能說得太快了。當我在外殼中時,這很好地工作。但是我不能在模板中使用'site.code_release_set.get(type =「I」)。release'。我得到以下錯誤 - '無法解析餘數:(type =「I」)。'site.code_release_set.get(type =「I」)。release'' –

+0

@RobPeterson因爲你不應該在Django模板中執行過濾。也許還有很多其他的解決方案,但第一個想到的是在Site模型中聲明自定義屬性(或方法),在那裏你訪問你需要的東西(例如創建具有以下語句的方法'get_release'返回自我。 code_release_set.get(類型= 「I」)。release')。然後你可以在你的模板'site.get_release' – mateuszb

0

您可以從一個網站訪問對象的發佈。首先,你可以把一個related_name有模型之間的反向關係的友好名稱:

site_id = models.ForeignKey('Site', on_delete=models.CASCADE, related_name="releases") 

,然後從一個站點對象,你可以做正常的查詢,發佈模式:

site.releases.all() 
site.releases.filter(...) 
... 
+0

非常感謝您的建議。 @mateuszb有我需要的信息。這增加了一些額外的理解以及我可以用「related_name」部分做什麼的知識。 –