【Django】複数のQuerySetを一つのQuerySetにする方法
Djangoで作成したモデルをobjects.filter()メソッド等で抽出した場合、
‘django.db.models.query.QuerySet’型のオブジェクトが返されます。
このQuerySetはテンプレート内でもviews.pyの中でもリストの用にして扱うことができます。
別々の条件でQuerySetを生成したけれど、一つのQuerySetとしてまとめて扱いたいという場合に複数のQuerySetを一つのQuerySetに結合する方法を解説します。
結論から言うと、unionメソッドを使うことで複数のQuerySetを結合することができます。以下ではunionメソッドの使い方を解説していきます。
前提
今回はnameとpriceをフィールドにもつProductというモデルを利用していきます。
Productは既に5つ用意してあり、それぞれをProduct.objects.all()で取得した結果をテンプレートから出力した結果が以下のようになっています。
all_products = Product.objects.all()
</table>
<hr>
<h2>Queryset_2</h2>
<table border="1">
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in Queryset_2%}
<tr>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
union()で結合する
それではさっそくunionの使い方を説明していきます。
まずは結合する前のQuerySetが必要なので、Productモデルからpriceが300のものと500のものをそれぞれfilter()メソッドで抽出していきます。
それぞれをqueryset_1、queryset_2という変数に代入しておき、それらをunionでまとめたものをqueryset_3とします。
以下のコードで上記のことを行っています。
views.py
from django.shortcuts import render
from .models import Product
# Create your views here.
def result(request):
all_products = Product.objects.all()
queryset_1 = Product.objects.filter(price=300)
queryset_2 = Product.objects.filter(price=500)
queryset_3 = queryset_1.union(queryset_2)
context = {
'all_products': all_products,
'queryset_1': queryset_1,
'queryset_2': queryset_2,
'queryset_3': queryset_3,
}
return render(request, 'result.html', context)
result.html
<h2>全商品</h2>
<table border="1">
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in all_products%}
<tr>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<hr>
<h2>Queryset_1</h2>
<table border="1">
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in queryset_1%}
<tr>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<hr>
<h2>Queryset_2</h2>
<table border="1">
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in Queryset_2%}
<tr>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<hr>
<h2>Queryset_3(Queryset_1 + Queryset_2)</h2>
<table border="1">
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in queryset_3%}
<tr>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
出力結果
まとめ
queryset_1.union(queryset_2)という構文で二つのQuerySetを一つにまとめることができます。
以下書籍を参考にしました。