There are three models
Product
: Having an id, a name
Storage
: Having an id, a name, a color and a branch
ProductStorage
: Maps each Product to a Storage and has some extra attributes.
I want to list all ProductStorages
with a specific Storage.branch
value grouped by the Storage, displaying storage name and color too.
Is it possible to do this in one query? I am new to Django and I am unsure how to do this in the most efficient way.
I know that I could query all ProductStorages and filter by branch. Then sort them maybe afterwards by their storages and query the storage-attributes in a second query. But I guess this won't be the best way to do it.
Example (All ProductStorages grouped by Storages):
"Storage.Name1, Storage.Color1":
ProductStorage.Name1, ProductStorage.attr1, ...
ProdcutStorage.Name2, ProductStorage.attr2, ...
ProductStorage.Name3, ProductStorage.attr3, ...
...
"Storage.Name2, Storage.Color2":
ProductStorage.Name1, ProductStorage.attr1, ...
ProdcutStorage.Name2, ProductStorage.attr2, ...
ProductStorage.Name3, ProductStorage.attr3, ...
...
Just query with the related Storage
and ProductStorage
s:
from django.db.models import Prefetch
products = Product.objects.prefetch_related(
Prefetch(
'productstorage_set', ProductStorage.objects.select_related('storage')
)
)
then we can group the items by the corresponding name
and color
:
from collections import defaultdict
for product in products:
product.items = defaultdict(list)
for item in product.productstorage_set.all():
product.items[item.storage.name, item.storage.color].append(item)
and pass products
to the template:
{% for product in products %}
<h1>{{ product.name }}</h1>
<ul>
{% for key, val in product.items %}
<li><b>{{ key.0 }} - {{ key.1 }}</b>
{% for item in val %}
<li>{{ item.name }} - {{ item.extra_attr }}</li>
{% endfor %}
</li>
{% endfor %}
</ul>
{% endfor %}