[Fixed]-Django-Weasyprint image issue

28👍

What exactly is the issue? Do you get anything in the logs? (You may need to configure logging if your server does not log stderr.) What does the generated HTML look like?

I’d really need answers to the above to confirm, but my guess is that the image’s URL is relative, but with HTML(string=...) WeasyPrint has no idea of what is the base URL. Try something like this. (I’m not sure of the Django details.)

HTML(string=html, base_url=request.build_absolute_uri()).write_pdf(response)

This will make a real HTTP request on your app, which may deadlock on a single-threaded server. (I think the development server defaults to a single thread.)

To avoid that and the cost of going through the network, you may want to look into writing a custom “URL fetcher”. It could be anywhere from specialized to just this one image, to a full Django equivalent of Flask-WeasyPrint.

2👍

Here it is a URL fetcher which reads (image) files locally, without performing an HTTP request:

from weasyprint import HTML, CSS, default_url_fetcher
import mimetypes

def weasyprint_local_fetcher(url):
    if url.startswith('local://'):
        filepath = url[8:]
        with open(filepath, 'rb') as f:
            file_data = f.read()
        return {
            'string': file_data,
            'mime_type': mimetypes.guess_type(filepath)[0],
        }
    return default_url_fetcher(url)

In order to use it, use the local:// scheme in your URLs, for example:

<img src="local://myapp/static/images/image.svg" />

Then, pass the fetcher to the HTML __init__ method:

html = HTML(
    string=html_string,
    url_fetcher=weasyprint_local_fetcher,
)
👤Luca

Leave a comment