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

在Django中生成PDF遇‘Context不可迭代’错误,求解决及替代方案

Django PDF生成问题:'Context'不可迭代错误解决与替代方案

Hey there! Let's tackle that PDF generation error you're hitting first, then go over some alternative tools you can use for generating PDFs in Django.

1. Fixing the 'Context is not iterable' Error

The root of your problem is how you're passing context to the template. Since Django 1.8, you don't need to wrap your context dictionary in a Context object anymore—template.render() accepts the raw dictionary directly. When you pass Context(context) to the render method, you're giving it a non-iterable object that xhtml2pdf's pisa can't process, hence the error.

Here's your corrected code with that fix, plus an optional error check for PDF generation:

from xhtml2pdf import pisa
from django.http import HttpResponse
from django.template.loader import get_template
from rest_framework.views import APIView
from .models import Brand

class ABCView(APIView):
    def post(self, request, format=None):
        report = Brand.objects.all()
        template_path = 'profile_brand_report.html'
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
        context = {'report': report}
        template = get_template(template_path)
        # Remove the Context wrapper here
        html = template.render(context)
        pisaStatus = pisa.CreatePDF(html, dest=response)
        
        # Optional: Handle PDF generation failures
        if pisaStatus.err:
            return HttpResponse('Failed to generate PDF. Please try again.', status=500)
        return response

2. Alternative PDF Generation Tools for Django

If you're looking for other reliable options beyond xhtml2pdf, here are three solid choices tailored to different use cases:

WeasyPrint

WeasyPrint excels at rendering modern HTML/CSS into PDFs, supporting features like flexbox, grid layouts, and custom fonts. It mimics browser rendering closely, so your PDF will match your web template's design perfectly.

Basic usage example:

from django.http import HttpResponse
from weasyprint import HTML
from django.template.loader import get_template
from rest_framework.views import APIView
from .models import Brand

class ABCView(APIView):
    def post(self, request, format=None):
        report = Brand.objects.all()
        template = get_template('profile_brand_report.html')
        html = template.render({'report': report})
        
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
        
        HTML(string=html).write_pdf(response)
        return response

ReportLab

ReportLab lets you build PDFs entirely with Python code, no HTML templates required. This is ideal if you need pixel-perfect control over elements like tables, charts, or custom page layouts (great for invoices, technical reports, or forms).

Quick example of a text-based PDF:

from django.http import HttpResponse
from reportlab.pdfgen import canvas
from rest_framework.views import APIView
from .models import Brand

class ABCView(APIView):
    def post(self, request, format=None):
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
        
        # Initialize PDF canvas
        pdf_canvas = canvas.Canvas(response)
        pdf_canvas.drawString(100, 750, "Brand Report")
        
        # Add brand data line by line
        y_pos = 730
        for brand in Brand.objects.all():
            pdf_canvas.drawString(100, y_pos, f"Brand: {brand.name} | Status: {brand.status}")
            y_pos -= 20
            # Start new page if content runs out of space
            if y_pos < 50:
                pdf_canvas.showPage()
                y_pos = 750
        
        pdf_canvas.showPage()
        pdf_canvas.save()
        return response

wkhtmltopdf + pdfkit

wkhtmltopdf is a command-line tool that uses the WebKit engine to convert HTML to PDF (supports JavaScript too, if enabled). The pdfkit Python library lets you integrate it with Django easily. This is a great pick if you need full browser-like rendering for complex pages.

Note: You'll need to install wkhtmltopdf on your server first, then install pdfkit via pip.

Basic usage:

import pdfkit
from django.http import HttpResponse
from django.template.loader import get_template
from rest_framework.views import APIView
from .models import Brand

class ABCView(APIView):
    def post(self, request, format=None):
        report = Brand.objects.all()
        template = get_template('profile_brand_report.html')
        html = template.render({'report': report})
        
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
        
        # Generate PDF and write directly to response
        pdfkit.from_string(html, response)
        return response

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:15:45