Hello everyone,
I’m trying to optimize SQL queries.
I have a model Company that has a method to count related objects.
class Company(models.Model):
name = models.CharField(max_length=100)
address = models.ForeignKey(Address, on_delete=models.PROTECT, default=None, null=True,
blank=True)
...
@property
def count_published_certificate(self):
return self.certificate_set.filter(published=True).count()
In the View the queryset is already ‘optimized’ for the related Address obj:
def company_list(request):
company_result = Company.objects.all().select_related('address').order_by('name')
form = CompanySearchForm()
return render(request, 'address_book/company_list.html',
{'form': form, 'company_results': company_result}
)
Finally in the template I make a loop and call the ‘count_published_certificate’ method on each loop iteration which cause a SQL query every iteration → BAD !
<ul id="list_company">
{% for company in company_results %}
<li class="company">
<div class="row">
<div id="" class="col-md-4">
<a href="{% url 'company-detail' company.id %}">
<span class="company_name">{{ company.name|upper }}</span>
<span>{% if company.legal_form %} {{ company.legal_form|upper }}{% endif %}</span>
</a>
</div>
<div id="" class="col-md-2">
{{ company.address.city|upper }}
</div>
<div id="" class="col-md-2">
{{company.address.zip|upper}}
</div>
<div id="" class="col-md-2">
{{company.address.country|upper}}
</div>
<div id="" class="col-md-2">
{{company.count_published_certificate}}
</div>
</div>
</li>
{% endfor %}
</ul>
How can I optimize this ?
I did think of creating a new field in the Company model. Increase or decrease a counter each time a Certificate obj with the field published=True is saved. But it seems very ‘non elegant’ option…
Any help would be much appreciated…