如何减少Django应用程序的查询量?

时间:2019-01-11 07:35:08

标签: python django

我的应用当前正在执行1000多次SQL查询,大约需要20秒钟来加载页面。我似乎找不到找到解决方案的方法,以更快地将相同的数据显示在模板的表中。我不会显示100个结果,因此我的分页设置为100。

这些是我的 models.py 中的方法,用于获取订单的数量和总和,这两个都在我的公司模型中,而get_order_count也在我的联系方式中

def get_order_count(self):
    orders = 0
    for order in self.orders.all():
        orders += 1
    return orders

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

views.py

class IndexView(ListView):
    template_name = "mailer/index.html"
    model = Company
    paginate_by = 100

模板

{% for company in company_list %}
    <tr id="company-row">
        <th id="company-name" scope="row">{{ company.name }}</th>
        <td>{{ company.get_order_count }}</td>
        <td id="order-sum">{{ company.get_order_sum|floatformat:2 }}</td>
        <td class="text-center">
           <input type="checkbox" name="select{{company.pk}}" id="">
       </td>
    </tr>
    {% for contact in company.contacts.all %}
        <tr id="contact-row">
            <th scope="row">&nbsp;</th>
            <td>{{ contact.first_name }} {{ contact.last_name }}</td>
            <td id="contact-orders">
                Orders: {{ contact.get_order_count }} 
            </td>
            <td></td>
        </tr>
    {% endfor %}
{% endfor %}

1 个答案:

答案 0 :(得分:8)

您的两种方法效率很低。您可以用注释替换它们,该注释可以在数据库中的一个查询中计算所有内容。您尚未显示您的模型,但是它类似于:

class IndexView(ListView):
    template_name = "mailer/index.html"
    model = Company.objects.annotate(order_count=Count('orders')).annotate(order_sum=Sum('contacts__orders__total'))
    paginate_by = 100

现在您可以访问{{ company.order_count }}{{ company.order_sum }}