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

Django视图调用ListView模板返回字符串供WeasyPrint生成PDF

核心问题答复

你完全可以通过配置ListView的context_object_name复用同一套模板,把渲染得到的HTML字符串直接传给WeasyPrint生成PDF,只要对齐视图和模板的上下文变量、替换成返回字符串的渲染方法即可,不需要额外复杂配置。

现有代码存在的几个会影响效果的问题
  • ListView的自定义上下文属性名存在拼写错误:代码中写的context_objecjt_name='cc'把object的最后一个t错写成了j,正确属性名是context_object_name,这个错误会导致自定义上下文名根本不生效。
  • 视图里的渲染方法选错了:在eprint函数里用的render()方法返回的是完整的HttpResponse响应对象,不是纯字符串形式的HTML内容,直接把这个对象传给WeasyPrint会解析失败,应该用render_to_string()直接拿到渲染后的字符串内容。
  • 模板变量名和上下文不匹配:当前模板里循环遍历的是默认的object_list,但你在PDF生成视图里传的上下文键是cc,两者对不上会导致循环拿不到任何数据,页面空白。
  • 模板的HTML结构有缺陷:当前代码里连续写了两个<form>开标签,没有闭合标签,会导致HTML结构错乱,WeasyPrint解析时可能出现样式偏移,顺手补上闭合标签即可。
调整方案和修正示例
  1. 先修正ListView的属性拼写,配置正确的context_object_name,让模板可以通过cc变量取到数据集,不管是ListView的常规列表页访问,还是PDF生成的自定义视图调用,都能复用同一份模板逻辑。
  2. 在eprint函数里引入render_to_string替代render(),直接获取字符串形式的渲染结果,传给WeasyPrint做解析。
  3. 调整模板里的循环遍历对象,把原来的object_list替换成统一的cc变量,保证上下文和模板的对应关系一致,同时补全缺失的HTML闭合标签。

修正后的eprint函数核心片段

from django.template.loader import render_to_string
from weasyprint import HTML

def eprint(request):
    checked = request.GET.getlist('marked[]')
    res = [Concert.objects.get(pk=l) for l in checked]
    # 直接获取渲染后的HTML字符串,不生成完整响应对象
    html_string = render_to_string('kammem/events.html', {'cc': res})
    # 把字符串传给WeasyPrint生成PDF
    html = HTML(string=html_string)
    html.write_pdf(target='pdf/test.pdf')

    fs = FileSystemStorage('pdf')
    with fs.open('test.pdf') as pdf:
        response = HttpResponse(pdf, content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="test.pdf"'
        return response

修正后的ListView代码

class Events(ListView):
    # 修正原代码的拼写错误
    context_object_name = 'cc'
    model = Concert
    template_name = 'kammem/events.html'

修正后的模板核心逻辑

{# 把遍历对象改成和上下文统一的cc变量 #}
{% for l in cc %}
  <tr>
    <td>
      <form>
        <label><input type="checkbox" id={{l.pk}} name="checkb"></label>
      </form>
    </td>
    <td><a href="eupdate/{{l.pk}}"><i class="bi bi-pencil-square"></i></a></td>
    <td><a href="edelete/{{l.pk}}"><i class="bi bi-trash"></i></a></td>
    <td>{{l.pk}}</td>
    <td>{{l.cname}}</td>
    <td><a href="detail/{{l.venue.pk}}">{{l.venue}}</a></td>
    <td>{{l.date}}</td>
    <td><a href="detail/{{l.organizer.pk}}">{{l.organizer}}</a></td>
    <td>{{l.antmus}}</td>
    <td>{{l.män1}}/{{l.kvinnor1}}</td>
    <td>{{l.publik}}</td>
    <td>{{l.män2}}/{{l.kvinnor2}}</td>
  </tr>
{% endfor %}
</tbody>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 12:45:05