Search code examples
djangodjango-staticfiles

django runserver can't find static files, but remote server can


I'm writing in Pycharm, pushing to PythonAnywhere via GitHub. Django3 and Python3.7. Working through the Django Girls tutorial.

I have defined in settings.py

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

I have a template with

{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="{% static "blog/css/blog.css" %}">
    <meta charset="UTF-8">
    <title>DG Tutorial</title>
</head>
...

I have tried python manage.py findstatic blog.css it can't find it. I try variations of static/blog/css/blog.css and /blog/css/blog.css and get a long error message that ends with:

django.core.exceptions.SuspiciousFileOperation: The joined path >>>(/blog.css) is located outside of the base path component (/Users/alesha/.virtualenvs/blog/lib/python3.7/site-packages/django/contrib/admin/static)

So, I'm wondering why it's not looking in the STATIC_ROOT, which is located outside the base path component. Or did it? I don't know.

I then checked the django bug-tracker. Nope - it's me.

So, the wacky part is that when I port the code to PythonAnywhere, it works just as it should, blog.css gets served and happiness abounds.

I have read a millihelen of posts on this, all the django tutorial pages on staticFiles - that I'm aware of, I've quad checked for typos. I am stumpeth - coz it works! Just not on localhost.

Thank you for helping with my first ever Stack Overflow question.

My Working Directories

The local and the remote


Solution

  • There are two solutions for this problem. It's a little bit confusing at first, but STATIC_ROOT directory should be empty. During the deployment when you run the manage.py collectstatic command, Django will look into each app's static subdirectory and will copy all the static files into STATIC_ROOT and the webserver will serve them from that directory (this is why it worked on PythonAnywhere). But by default the findstatic command will not look for static files in STATIC_ROOT directory. The quick workaround is just add STATIC_ROOT to STATICFILES_DIRS in settings.py then Django will look for static files in that directory as well.

    But my recommendation is that you should follow the "official" way to store the static files which is inside an app's static subdirectory (e.g. mysite/blog/static/blog/css/blog.css) and keep STATIC_ROOT empty.