0
votes

I have my django app hosted on pythonanywhere. I am using weasyprint to generate a pdf and there is an image to be shown in my pdf. The error in the error log is "Failed to load image at /static/images/logo.png". When I try to open the same path as url, it shows me the image in the browser. Which means it is getting the path right but something else is wrong.

I have my static directory placed outside the app. And this path is added to the settings file.

My folder structure:

     my_app
     static
        |__ css
        |__ images
              |__ logo.png
        |__ js
     templates
        |__ my_app
              |__ pdf.html

settings.py:

STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS =[
    STATIC_DIR,
]

pdf.html:

{% load static %}
<td><img class="my_logo" src="{% static 'images/logo.png' %}" alt="Temporarily Unavailable"></td>
2
try "STATIC_URL = './static/'" - Manjunath Siddappa
Rename STATIC_DIR to STATIC_ROOT. And remove it from STATICFILES_DIRS: STATICFILES_DIRS is the list of source folders that will be scanned during collectstatic to fill destination folder - STATIC_ROOT. - Ivan Starostin
@IvanStarostin so actually STATICFILES_DIRS is correct, since this is where the source static files are located. What's missing is a STATIC_ROOT directory outside of the project and running manage.py collectstatic to copy the static files from the static directory inside the project repository to the location from where they are served. - dirkgroten
directory outside of the project looks like OP does not have such a directory. - Ivan Starostin
then OP should add such a directory. you should never serve static files on production from within your project (source code) directory. Your entire project directory should only be accessible by your app server (WSGI), but not to your web server. - dirkgroten

2 Answers

3
votes

Assuming the folder structure you are showing is what you use on your development machine and reflects your actual code repository.

Your settings are correct:

  • STATICFILES_DIRS lists the directories (outside of the apps) where you put your static files
  • STATIC_URL is the url used to prefix the static location, telling the server "any url that starts with this, you need to go fetch a static file".

What's missing is:

  • STATIC_ROOT: where should collectstatic copy your static files to? This is normally a location outside of your project repository, sometimes even on an entirely different machine, where your web server will serve the static files from. In a simple deployment, it can be a /static directory at the same level as your project:
/home/myusername/my_project_www/
     |_ my_project/   <-- BASE_DIR (this is a git clone of your code)
          |_ my_project
                |_ settings.py
                |_ urls.py
          |_ app/
              |_ views.py
              |_ static/  <-- automatically used as source by Django
          |_ manage.py
          |_ static/  <-- added to STATICFILES_DIRS
          |_ ...
     |_ static/  <-- STATIC_ROOT all files will be copied and served from here
     |_ media/  <-- MEDIA_ROOT if users can upload files

In the above example, you would set STATIC_ROOT = os.path.abspath(os.path.join(os.path.dirname(BASE_DIR), 'static')) (one directory above BASE_DIR).

  • Then you need to run manage.py collectstatic so that all static files are copied into that directory.

  • And finally in the pythonanywhere console, in the Static Files section, you have to map the /static/ url to the location of STATIC_ROOT, i.e. /home/username/my_project_www/static/ for path. (Or if you're running your own server, you need to configure this in your nginx or apache configuration).

I've written a blog post about this.

0
votes

Are you trying to make a pdf for the user to download, or are you trying to display a html file?

If you are using weasyprint to generate a pdf, then weasyprint will not try to access http://yourwebsite/static/images/logo.png to get the logo to put into the pdf. Instead it will try to access the file on your server at /static/images/logo.png.

If all you want to do is to have the logo in your pdf, you should instead get weasyprint to say put in the logo from /home/username/path/to/your/logo/file.png instead.