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

Django集成Weasyprint生成PDF无法加载静态资源报错问询

问题根因

你自定义的url_fetcher仅对file://协议开头的资源生效,但你在初始化HTML对象时传入了base_url=request.build_absolute_uri("/"),导致模板渲染后的静态资源地址为完整的HTTP地址(如http://api.dashboard.localhost:8000/static/logos/logo.png),不会触发你写的本地文件读取逻辑,直接走WeasyPrint默认的网络请求逻辑。而你的Docker容器内部没有配置api.dashboard.localhost的hosts映射,所以发起网络请求时会出现域名解析失败的报错。

解决方案

方案1:修改url_fetcher适配HTTP协议的本站静态资源(推荐)

调整url_fetcher的判断逻辑,不管资源是http/https还是file协议,只要路径符合静态/媒体资源的前缀规则,就直接从本地读取:

def url_fetcher(url, *args, **kwargs):
    parsed_url = urlparse(url)
    url_path = parsed_url.path
    # 处理媒体资源
    default_media_url = settings.MEDIA_URL in ('', get_script_prefix())
    if not default_media_url and url_path.startswith(settings.MEDIA_URL):
        mime_type, encoding = mimetypes.guess_type(url)
        media_root = settings.MEDIA_ROOT
        if isinstance(settings.MEDIA_ROOT, Path):
            media_root = f'{settings.MEDIA_ROOT}/'
        path = url_path.replace(settings.MEDIA_URL, media_root, 1)
        return {
            'mime_type': mime_type,
            'encoding': encoding,
            'filename': Path(url_path).name,
            'file_obj': default_storage.open(path)
        }
    # 处理静态资源
    elif settings.STATIC_URL and url_path.startswith(settings.STATIC_URL):
        mime_type, encoding = mimetypes.guess_type(url)
        path = url_path.replace(settings.STATIC_URL, '', 1)
        return {
            'mime_type': mime_type,
            'encoding': encoding,
            'filename': Path(url_path).name,
            'file_obj': open(find(path), 'rb')
        }
    # 外部资源走默认请求逻辑
    return weasyprint.default_url_fetcher(url, *args, **kwargs)

方案2:修改base_url为本地协议

初始化HTML对象时不传入HTTP协议的base_url,直接使用file://协议指向项目根目录,适配原有url_fetcher逻辑:

HTML(
    string=template_string, 
    base_url=f'file://{settings.BASE_DIR}/', 
    url_fetcher=url_fetcher
).write_pdf(results)

方案3:Docker容器配置hosts映射

如果确实需要走网络请求获取资源,可以在Docker运行配置中添加hosts映射,将域名指向本机:

  • docker运行命令添加参数:
    docker run --add-host api.dashboard.localhost:127.0.0.1 <其余运行参数>
    
  • docker-compose配置添加字段:
    services:
      你的服务名:
        extra_hosts:
          - "api.dashboard.localhost:127.0.0.1"
    

额外检查项

  • 模板中引用的是logos/logo.jpg,报错信息中显示的是logo.png,请确认静态目录下的文件后缀是否匹配,避免文件不存在的问题
  • 生产环境部署后请确认已执行collectstatic命令,保证find()方法可以正常找到对应的静态文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:15:03