Django annotate - проблема с подсчетом вложенных элементов в шаблоне
У меня есть список флажков и меток для бизнес-заявок. Я хотел бы применить категории для каждого бизнес-заявления, но мне трудно подсчитать количество бизнес-заявлений в каждой категории.
Вот что у меня есть:
models.py
class BusinessChallangeCategory(models.Model):
title = models.CharField(max_length=300)
class BusinessChallange(models.Model):
title = models.CharField(max_length=300)
category = models.ForeignKey(BusinessChallangeCategory, on_delete=models.CASCADE, related_name='category_business_challange')
class Product(models.Model):
title = models.CharField(max_length=300)
business_challange = models.ManyToManyField(BusinessChallange, related_name='business_challange_product')
views.py
class ManualSearch(ListView):
template_name = 'test.html'
model = Product
queryset = Product.objects.filter(status=1)
def get_context_data(self, **kwargs):
context = super(ManualSearch, self).get_context_data(**kwargs)
business_challange = BusinessChallangeCategory.objects.annotate(business_challange_count=Count('category_business_challange__business_challange_product'))
context['business_challange'] = business_challange
return context
test.html
<div class="filter-container" id="business-challange-list">
<strong class="f-12">Business challanges</strong><br>
{% for bc_category in business_challange %}
<div class="fw-bold f-12">{{bc_category.title}}</div>
{% for bc in bc_category.category_business_challange.all %}
<div class="form-check d-flex business-challange-item">
<input class="form-check-input" type="checkbox" value="{{bc.title}}" id="{{bc.title}}" data-filter="business_challange">
<label class="form-check-label ps-2" for="{{bc.title}}">
{{bc.title}}
</label>
<span class="ms-auto ps-2 text-muted f-12">{{bc.business_challange_count}}</span> #count is not working, it doesn't appear at all
</div>
{% endfor %}
{% endfor %}
</div>
Любой совет о том, что я делаю неправильно и как правильно рассчитать каждый бизнес-задание в каждой категории, будет оценен по достоинству
Вы аннотируете значение в одном кверисете в шаблоне business_challange
, но затем пытаетесь получить к нему доступ во время итерации другого кверисета bc_category.category_business_challange.all
, который вызывает DB при каждом запуске. Вам не нужна аннотация, хотя вы можете вызвать непосредственно {{bc.business_challange_product.count}}
. При этом каждый раз будет выдаваться еще один запрос.
С точки зрения производительности я бы рекомендовал аннотировать подсчет на втором наборе запросов BusinessChallange
непосредственно в представлении, вместо BusinessChallangeCategory
и группировать по категориям в python, так вы получите то, что вам нужно в одном запросе и одной итерации forloop.