Django ORM で順参照の逆参照 | SEの道標
django

Django ORM で順参照の逆参照

順参照ー逆参照の組合せ

順参照は select_related (INNER JOIN), 逆参照は prefetch_related (2 つの SQL クエリーをメモリ内で Django が連結) で対応するわけだが、組み合わせたいときはそのパターンによって書き方がある。

以下のサイトで色々な組合せが書いてあるが

Django ORM にて SQL発行数を抑えながら順参照、逆参照する方法

順参照-逆参照のパターンが無かったのでここに記す。

prefetch_related("foo__bar_set")

上記の書き方をすると、その後のコードでは foo__bar_set.all() という使い方しかできない。foo__bar_set.filter(hoge=fuga) 等のように filter を使うと上記プリフェッチは無効になる。

もし filter を使うのなら to_attr でフィールドに格納するのだが、その場合は foo を経由して呼び出すことになる。

例えば上記サイトのモデルをベースに、Department への順参照をする Asset というモデル (Asset の FK として department_id ) があるとする。

employees = Employee.objects.all().prefetch_related(
    "department__asset_set", queryset=Asset.objects.filter(name__icontains="テスト"), to_attr="assets"
)

こうした場合、assets には Asset のインスタンスの list が格納されている。(queryset ではない)

このインスタンスの list を呼び出すには

for employee in employees:
    my_asset_list = employee.department.assets

と department を経由して assets を呼び出す。

コメント

タイトルとURLをコピーしました