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

Django core.serializers序列化速度过慢,如何优化以提升结果展示效率?

问题描述

你在Django视图中使用django.core.serializers进行序列化,功能正常但有时展示结果表格需要超过1分钟,视图代码如下:

# views.py
from django.core import serializers
def search_institution(request):
    form = SearchInstitutionsForm()
    qs = Institution.objects.all()
    if request.method == "POST":
        form = SearchInstitutionsForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            if cd['name']:
                qs = Institution.objects.filter(name__contains=cd['name'])
            print(f"Before requesting from db: {datetime.now()}")
            print(f"After requesting from db, before serializing: {datetime.now()}")
            context = { 
                "result_data": SafeString(serializers.serialize("json", qs)), 
                'form': form 
            }
            print(f"After serializing, before rendering: {datetime.now()}")
            return render(request, "landing/result_table.html", context)
    else:
        context = { "form": SearchInstitutionsForm }
        return render(request, "stakeholders/institution_form.html", context)
序列化速度优化方案

嘿,我看了你的问题和代码,序列化慢确实很影响用户体验,这里有几个实用的优化方案,你可以根据自己的场景来选择:

  • 替换Django自带序列化器,手动构建数据
    Django自带的serializers.serialize会额外处理很多元数据(比如模型的app_label、主键类型等),如果你的前端不需要这些冗余信息,完全可以手动构建只包含所需字段的字典,再用JSON工具序列化,速度会快很多。示例代码:

    import json
    # 只提取你需要的字段,避免不必要的序列化处理
    result_data = []
    for inst in qs:
        result_data.append({
            "id": inst.id,
            "name": inst.name,
            # 这里添加其他需要展示的字段
        })
    # 替换成手动序列化的结果
    context = { 
        "result_data": SafeString(json.dumps(result_data)), 
        'form': form 
    }
    
  • 优化数据库查询,避免N+1问题
    如果Institution模型有外键、多对多等关联字段,序列化时可能会触发多次数据库查询(也就是N+1问题),拖慢整体速度。你可以用select_related(针对外键/一对一)或prefetch_related(针对多对多/反向外键)提前把关联数据一次性查询出来:

    # 假设有外键category,用select_related预取
    qs = Institution.objects.filter(name__contains=cd['name']).select_related('category')
    # 如果是多对多关系比如tags,用prefetch_related
    qs = Institution.objects.filter(name__contains=cd['name']).prefetch_related('tags')
    

    这样数据库只需要一次查询,序列化时就不用反复访问数据库了。

  • 对大量结果进行分页处理
    如果查询返回的数据集很大(比如上千条),一次性序列化所有数据肯定慢,而且前端渲染大表格也会卡顿。可以用Django的Paginator做分页,每次只处理和返回一页的数据:

    from django.core.paginator import Paginator
    # 设置每页显示20条,可根据需求调整
    paginator = Paginator(qs, 20)
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)
    
    # 只序列化当前页的数据
    result_data = []
    for inst in page_obj:
        result_data.append({
            "id": inst.id,
            "name": inst.name
        })
    
    # 把分页信息传给前端,方便做翻页控件
    context = {
        "result_data": SafeString(json.dumps(result_data)),
        "page_obj": page_obj,
        'form': form
    }
    
  • 使用更快的JSON序列化库
    标准库的json模块可以换成更高效的第三方库,比如ujson,它的序列化速度比标准库快不少。安装后直接替换即可:

    import ujson
    # 用ujson替代json进行序列化
    context = { 
        "result_data": SafeString(ujson.dumps(result_data)), 
        'form': form 
    }
    
  • 缓存重复查询的结果
    如果你的机构数据不是实时更新的,可以把查询和序列化后的结果缓存起来,相同的搜索请求直接返回缓存内容,省去重复的数据库查询和序列化步骤:

    from django.core.cache import cache
    # 用搜索关键词作为缓存键,确保唯一性
    cache_key = f"institution_search_{cd['name']}"
    cached_data = cache.get(cache_key)
    
    if not cached_data:
        # 没有缓存时才查询和序列化
        result_data = []
        for inst in qs:
            result_data.append({
                "id": inst.id,
                "name": inst.name
            })
        cached_data = ujson.dumps(result_data)
        # 设置缓存有效期,比如1小时(根据数据更新频率调整)
        cache.set(cache_key, cached_data, 3600)
    
    context = { 
        "result_data": SafeString(cached_data), 
        'form': form 
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:04:08