Django の models.py で ForeignKey や ManyToManyField で他のモデルを参照する形になるとき、テンプレートでその他モデルのデータを引っ張って表示したい事も多いと思います。
と言うかそのために他テーブルを参照する事がほとんどかと思います。
いわゆる Join した形をイメージしますが、実は Join するために models.py で特別なことをする必要はほとんどありません。テンプレート上の記述を少し変更すれば完了します。
1. 芸人、事務所、番組の例
芸人、事務所、番組の例で説明します。
#models.py class JimushoMaster(models.Model): # 芸人の所属事務所 jimusho_name = models.CharField(max_length=20) class BangumiMaster(models.Model): # 芸人の出演番組 bangumi_name = models.CharField(max_length=60, null=False, unique=True) class GeininMaster(models.Model): name = models.CharField(max_length=20, null=False) # 芸人の名前 jimusho = models.ForeignKey(JimushoMaster, on_delete=models.PROTECT) # 事務所との紐付き(一対多) bangumi = models.ManyToManyField(BangumiMaster) # 番組との紐付き(多対多)
芸人と事務所は一体多の関係、芸人と番組は多対多の関係になります。たぶん。
2. ForeignKey(外部キー)
まずは ForeignKey のケースから。
GeininMaster を渡しているテンプレート上で、JimushoMaster の jimusho_name の値を表出したいとします。
この場合 Template 上では「object名.外部キー項目.参照先テーブルの項目」まで入れるとテンプレート上に値を表示させられます。
{{ object.jimusho.jimusho_name }}
この様な感じです。
models.py で def __str__(self): を記述した場合の注意点
ForeignKey の参照先のモデル(この例では JimushoMaster)のクラス定義で「def __str__(self):」を記述している場合、テンプレートで「object.jimusho」までを指定すると、
def __str__(self):で参照している値がそのまま表出されます。
逆に「object.jimusho.jimusho_name」まで記述しても何も表出されないので気をつけてください。
3. ManyToManyField の場合
続いて ManyToManyField で参照している値をテンプレートに表出したい場合。
これまた GeininMaster を渡しているテンプレート上で、BangumiMaster の bangumi_name の値を表出したいとします。
ListView の例になりますが、View から受け取るオブジェクトの一つ一つに対して複数の ManyRelatedManager オブジェクトが返ってくるので一つずつ表出します。
下記の様な感じです。
{% for geinin in object_list %} # 各芸人に対して {% for i in geinin.bangumi.all %} # 複数のオブジェクトが返ってくるので {{ i.bangumi_name }} # オブジェクトごとに番組名を表出 {% endfor %} {% endfor %}