2017-02-08 10 views
0

私は、QuerySetを介して関連している複数のモデルのデータを表示しようとしています。最終的な目標は、Siteモデルのいくつかの情報と、Siteモデルのsw_delivery_dateの日付範囲フィルタに基づく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)]) 

があるので、私は、しかし、私の基準を満たすサイトモデル内のすべてのオブジェクトを取得することができますサイトとCode_Releaseとの間には関係がありません(逆に1対多があります)、Code_Releaseデータは取得できません。

forループを実行すると、上記のクエリから返されたすべてのサイトを反復処理し、Code_Releaseモデルからデータを選択することができます。これにより、PpackおよびRingモデルから関連データを取得できます。

しかし、それは複数のデータベースヒットと、おそらくテンプレートでの解析が困難な場合があります。

これに基づいて、私はCode_Releaseモデルから選択する必要があると考えていました。これは、SiteモデルとPpackモデル(Ringモデルに関連しています)の両方に関連しています。私は正しいクエリを作成するために苦労しました/私が欲しいものを達成するこの方法でデータにアクセスしますが、これは正しい方法だと思います。

これをどのようにして最高に達成できますか?

+0

してください:あなたはモデルリリースに正常なクエリを作ることができるサイトオブジェクトから、その後、

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

と:まず、あなたは、モデル間の逆関係のフレンドリ名を持つようにrelated_nameを置くことができます明確にする - 目標はCode_Releaseオブジェクトのセットを取得することですか?それらに加えてどんな関係が必要ですか? –

+0

サイト名、sw_delivery_date、リリース情報(Ppackモデルのstr表現)、およびassigned_tech –

答えて

0

ここでは、[RelatedManager]を使用できます。 ForeignKeyを宣言すると、Djangoでは逆の関係にアクセスできます。具体的には、特定の1つのサイトを指し示す複数のコードリリースがあるとします。 <your_model_name_lowercase>_set属性を使用してサイトオブジェクト経由ですべてにアクセスできます。だからあなたの場合:

site.code_release_set.all() 

は、サイトオブジェクトからのリリースにアクセスすることができます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 ")からのリリース。リリース" –

+0

@RobPeterson Djangoテンプレート内でフィルタリングを実行します。おそらく他にもたくさんの解決策がありますが、最初に思いついたのは、必要なものにアクセスするサイトモデルでカスタムプロパティ(またはメソッド)を宣言することでした(たとえば、次のステートメント 'return selfを持つget_release'メソッドを作成します)。 code_release_set.get(type = "I")。release')。それから、テンプレート 'site.get_release' – mateuszb

0

をオブジェクトへのForeignKeyを持つすべてのコードリリースオブジェクトのクエリセットを返します。

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

お寄せいただきありがとうございます。 @mateuszbに必要な情報がありました。これにより、「related_name」の部分で何ができるのかをさらに理解し、知識を得ることができました。 –

関連する問題