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

Django中如何反序列化已存入session的序列化QuerySet?

方案1:将序列化JSON转为模型实例集合(不推荐)

注意:已经序列化后的JSON数据无法转回原生QuerySet对象,QuerySet是Django ORM中绑定数据库查询的懒加载代理对象,序列化后得到的是数据快照,仅能还原为模型实例的集合,足够满足导出Excel的遍历需求。
操作代码如下:

from django.core import serializers

def export_excel_view(request):
    rp = request.session.get('report')
    if not rp:
        # 自行补充无数据时的异常处理逻辑
        ...
    # 直接反序列化json字符串得到模型实例列表
    ipd_instances = [item.object for item in serializers.deserialize("json", rp)]
    # 后续遍历ipd_instances写入Excel即可

该方案存在以下明显问题:

  • Django默认session存储有大小上限,数据量较大时会存储失败
  • 序列化、反序列化过程有额外性能损耗,数据量越大损耗越明显
  • session中存储的是数据快照,若期间数据库对应记录有更新,导出的是过期旧数据

方案2:更合理的实现方案(推荐)

不要在session中存储整个结果集,改为存储筛选参数,导出时重新查询数据库得到原生QuerySet,完全避免上述问题。
首先修改原ipd_report_view逻辑:

def ipd_report_view(request):
    report=IpdReport.objects.all()
    myFilter=IpdFilters(request.POST, queryset=report)
    report=myFilter.qs
    # 存储筛选参数,而非序列化后的结果集
    request.session['ipd_filter_params'] = request.POST.dict()
    total1=report.aggregate(Sum('realization__amount_received'))
    total2=report.aggregate(Sum('realization__deficit_or_surplus_amount'))
    context={'report': report, 'total1':total1, 'total2':total2, 'myFilter':myFilter}
    return render(request, 'account/ipdreport.html', context)

导出视图逻辑:

def export_excel_view(request):
    filter_params = request.session.get('ipd_filter_params', {})
    # 用存储的筛选参数重新查询得到原生QuerySet
    report_qs = IpdFilters(filter_params, queryset=IpdReport.objects.all()).qs
    # 直接用report_qs实现Excel导出逻辑即可
    ...

该方案优势:

  • 无需处理序列化、反序列化逻辑,代码更易维护
  • 仅存储筛选参数,session存储占用极小,不受数据量大小限制
  • 导出时查询最新数据库数据,不会出现数据不一致问题
  • 得到原生QuerySet,支持所有ORM操作,灵活度更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:06:07