Я пытаюсь решить проблемы с производительностью на веб-сайте, основанном на Django, с очень небольшими знаниями синтаксиса Django и Python. Кажется, я правильно определил проблему. Кажется, я также знаю, что делать дальше, но не могу понять синтаксис Python / Django, чтобы все работало.
class Company(models.Model):
name = models.CharField(max_length=100)
bic = models.CharField(max_length=100, blank=True)
def get_order_count(self):
return self.orders.count()
def get_order_sum(self):
total_sum = 0
for contact in self.contacts.all():
for order in contact.orders.all():
total_sum += order.total
return total_sum
class Contact(models.Model):
company = models.ForeignKey(
Company, related_name="contacts", on_delete=models.DO_NOTHING)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True)
def get_order_count(self):
return self.orders.count()
class Order(models.Model):
order_number = models.CharField(max_length=100)
company = models.ForeignKey(Company, related_name="orders", on_delete=models.DO_NOTHING)
contact = models.ForeignKey(Contact, related_name="orders", on_delete=models.DO_NOTHING)
total = models.DecimalField(max_digits=18, decimal_places=9)
order_date = models.DateTimeField(null=True, blank=True)
def __str__(self):
return "%s" % self.order_number
Я догадываюсь, что проблемы с производительностью вызваны вложенным циклом в get_order_sum
. И мое решение вполне понятно: вложенные «fors» должны быть заменены простой командой, которая использует агрегирование и использует собственную эффективную внутреннюю функциональность SQL базы данных. Поэтому, на мой взгляд, решение должно выглядеть примерно так:
return self.contacts.all().orders.all().aggregate(Sum('total'))
Проблема в том, что я не могу понять, как правильно написать то, что я хочу, чтобы Django / Python делал. Пожалуйста, помогите мне!
Или я ошибаюсь и проблема (или ее часть) в моем View-коде?
<table>
<tr>
<th>Name</th>
<th>Order Count</th>
<th>Order Sum</th>
<th>Select</th>
</tr>
{% for company in company_list|slice:":100" %}
<tr>
<td>{{ company.name }}</td>
<td>{{ company.orders.count }}</td>
<td>{{ company.get_order_sum|floatformat:2 }}</td>
<td><input type="checkbox" name="select{{company.pk}}" id=""></td>
</tr>
{% for contact in company.contacts.all %}
<tr>
<td>- {{ contact.first_name }} {{ contact.last_name }}</td>
<td>Orders: {{ contact.orders.count }}</td>
<td> </td>
<td> </td>
</tr>
{% endfor %}
{% endfor %}
</table>
Буду также признателен за любые другие советы и мнения о том, как можно улучшить этот код (особенно из POV производительности).