wkhtmltopdf在Django项目中导出PDF无法渲染图片问题求助
解决方案
核心原因
wkhtmltopdf渲染PDF时无法识别Django默认返回的相对资源URL,也不会自动携带当前用户的会话凭证访问受限资源,是图片加载失败的核心原因。
- 方案1:使用绝对资源路径(最通用)
首先修改视图代码,确保上下文携带request对象:
class MyPDF(PDFTemplateView): template_name = 'templates/post_detail.html' # 配置wkhtmltopdf基础参数 cmd_options = { 'enable-local-file-access': True, 'no-stop-slow-scripts': True, } def get_context_data(self, pk, **kwargs): # 调用父类方法获取默认上下文,默认包含request对象 context = super().get_context_data(**kwargs) context['post'] = Post.objects.get(pk=pk) return context
然后修改模板中的图片标签,拼接完整绝对URL:
<img src="{{ request.build_absolute_uri(post.image.url) }}" />
如果是服务器本地存储的图片,也可以直接读取本地文件路径,跳过网络请求,稳定性更高:
<img src="file://{{ post.image.path }}" />
生产环境请确保媒体资源由Nginx/Apache等Web服务托管,不要使用Django默认的开发模式资源服务,避免资源访问失败。
- 方案2:携带会话凭证访问受限资源
如果你的媒体资源配置了登录权限校验,需要给wkhtmltopdf传递当前用户的会话cookie,修改视图代码:
class MyPDF(PDFTemplateView): template_name = 'templates/post_detail.html' def get_cmd_options(self): options = super().get_cmd_options() # 传递当前会话cookie session_id = self.request.COOKIES.get('sessionid') csrf_token = self.request.COOKIES.get('csrftoken') options.update({ 'cookie': [ ('sessionid', session_id), ('csrftoken', csrf_token) ], 'enable-local-file-access': True, }) return options def get_context_data(self, pk, **kwargs): context = super().get_context_data(**kwargs) context['post'] = Post.objects.get(pk=pk) return context
- 方案3:HTTPS资源适配
如果你的图片是HTTPS协议的线上资源,添加忽略证书校验的参数即可:
cmd_options = { 'enable-local-file-access': True, 'no-check-certificate': True, }
内容的提问来源于stack exchange,提问作者Syed
相关产品推荐
相关产品推荐

