python - 如何减少我的 Django 应用程序的查询量?
问题描述
我的应用程序目前正在执行 1000 多个 SQL 查询,并且需要大约 20 秒来加载页面。我似乎无法找到一种方法来提出解决方案,以更快地在我的模板中的表格上显示相同的数据。我不想显示 100 个结果,所以我的分页设置为 100。
这些是我的models.py 中用于获取订单数量和总和的方法,这两个在我的 Company 模型中,get_order_count 也在我的 Contact 模型中
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
视图.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"> </th>
<td>{{ contact.first_name }} {{ contact.last_name }}</td>
<td id="contact-orders">
Orders: {{ contact.get_order_count }}
</td>
<td></td>
</tr>
{% endfor %}
{% endfor %}
解决方案
Your two methods are very inefficient. You can replace them with annotations which calculate everything in one query in the database. You haven't shown your models, but it would be something like:
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
Now you can access {{ company.order_count }}
and {{ company.order_sum }}
.
推荐阅读
- graphql - Nextjs 与 ApolloClient 具有基本路由到单独的 graphql 服务器
- flutter - Flutter - 用户数据的客户端加密
- javascript - 从 AJAX 调用更改 PHP 会话变量
- ssh - 使用 ssh 连接到服务器时运行脚本
- sql - Oracle SQL 触发器 - 如何读取每个新行
- reactjs - 数据表中的列过滤器
- node.js - 电子 NPM 错误!缺少脚本:开始
- apache-flink - Flink jdbc sink 未在 web ui 中提交
- flutter - 如何根据列表中的数据在颤动中渲染多个小部件?
- angular - Angular:在运行时评估自定义字符串