You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Django项目中HR列表页的加载速度?

Django HR列表页加载优化方案

针对1200条数据加载耗时近10秒的问题,核心优化方向是解决ORM查询的N+1问题,辅以分页、缓存等手段,具体方案如下:

1. 解决N+1查询问题(核心优化)

当前ListView默认的queryset会触发N+1查询:加载1200条HR数据后,模板渲染时每访问一个外键字段(如year_scenario_version)都会单独发起一次数据库请求,累计产生大量重复查询,这是耗时的主要原因。

修改views.py,使用select_related预加载所有关联的外键对象,将多次查询合并为一次:

class HRListView(Budgetlevel2Mixin, BudgetMixin, LoginRequiredMixin, ListView):
    model = HR
    template_name = "budget/hr_list.html"
    # 预加载所有外键关联对象,避免N+1查询
    queryset = HR.objects.select_related(
        'year_scenario_version',
        'measure_name',
        'employee_type',
        'employee_level',
        'subsidiary',
        'department',
        'currency'  # 模型中定义的外键,即使模板未用到也建议预加载避免后续风险
    )

如果需要动态调整查询条件,可重写get_queryset方法:

def get_queryset(self):
    return super().get_queryset().select_related(
        'year_scenario_version', 'measure_name', 'employee_type',
        'employee_level', 'subsidiary', 'department', 'currency'
    )

2. 分页处理

一次性渲染1200条数据会增加DOM渲染时间,同时加大数据库查询压力。通过分页将数据拆分,每次仅加载部分数据:

修改views.py添加分页配置:

class HRListView(Budgetlevel2Mixin, BudgetMixin, LoginRequiredMixin, ListView):
    model = HR
    template_name = "budget/hr_list.html"
    queryset = HR.objects.select_related(...)  # 保留上述预加载配置
    paginate_by = 20  # 每页显示20条,可根据需求调整

在hr_list.html末尾添加分页导航:

{% block pagination %}
{% if is_paginated %}
<div class="pagination">
    <span class="page-links">
        {% if page_obj.has_previous %}
            <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
        {% endif %}
        <span class="page-current">
            第 {{ page_obj.number }} 页 / 共 {{ page_obj.paginator.num_pages }} 页
        </span>
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">下一页</a>
        {% endif %}
    </span>
</div>
{% endif %}
{% endblock %}

3. 模板缓存优化(可选)

如果HR数据不是实时更新,可通过模板缓存减少重复渲染耗时:

在hr_list.html顶部加载缓存标签,并缓存整个列表区域:

{% load cache %}
<!-- 缓存5分钟,按用户ID区分缓存(如果不同用户看到的数据不同) -->
{% cache 300 hr_list request.user.id %}
{% block thead %}
<!-- 原表头代码 -->
{% endblock %}

{% block tbody %}
<!-- 原表体循环代码 -->
{% endblock %}

{% block pagination %}
<!-- 分页代码 -->
{% endblock %}
{% endcache %}

4. 数据库索引检查

确认HR模型的所有外键字段已创建索引(Django默认会为ForeignKey自动创建索引,但若手动修改过模型需验证)。若有常用的排序/过滤字段,可额外添加索引以加速查询。


内容的提问来源于stack exchange,提问作者user13719970

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:11:08