Forums

Django 301/401 error when serving static files in production

Edit: 301/404 error NOT 301/401

I'm trying to deploy a Django + Mezzanine app, but I'm running into a lot of 404 errors when serving static files (in production). The exact error is as follows:

2017-01-31 21:44:44,981 :Not Found: /static/custom/css/bootstrap.min.css/
2017-01-31 21:44:45,012 :Not Found: /static/custom/css/bootstrap-material-design.min.css/
2017-01-31 21:44:45,042 :Not Found: /static/custom/css/animate.css/
2017-01-31 21:44:45,072 :Not Found: /static/custom/css/dots.css/
2017-01-31 21:44:45,102 :Not Found: /static/custom/css/ripples.min.css/
2017-01-31 21:44:45,133 :Not Found: /static/custom/css/swiper.min.css/

My Chrome console displays the following:

    /static/custom/css/bootstrap.min.css       301 (Permanent redirect)
.....and then below that i get:
    /static/custom/css/bootstrap.min.css/      404 (Not found)
.....notice the forward slash at the end???

My project structure is as follows:

robot/         ("robot/" is the main project folder where manage.py is)
    - apps/
        - app1/
        - app2/
    - robot/
        - settings.py
        - urls.py
        - wsgi.py
     - static/
     - media/
     - manage.py
     - requirement.txt

Here are my settings.py:

PROJECT_APP_PATH = os.path.dirname(os.path.abspath(__file__))
PROJECT_APP = os.path.basename(PROJECT_APP_PATH)
PROJECT_ROOT = BASE_DIR = os.path.dirname(PROJECT_APP_PATH)
CACHE_MIDDLEWARE_KEY_PREFIX = PROJECT_APP
WSGI_APPLICATION = 'robot.wsgi.application'
ROOT_URLCONF = "%s.urls" % PROJECT_APP

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
MEDIA_URL = STATIC_URL + "media/"
MEDIA_ROOT = os.path.join(PROJECT_ROOT, *MEDIA_URL.strip("/").split("/"))

My "Web" tab settings are as follows:

Source code:
/home/Robot/robot/

Working directory:
/home/Robot/

WSGI configuration file:
/var/www/robot_pythonanywhere_com_wsgi.py

Virtualenv:
/home/Robot/.virtualenvs/robot-virtualenv

My wsgi file is as follows:

import os
import sys

# add project folder to path
path = '/home/Robot/robot'
if path not in sys.path:
    sys.path.append(path)

# Remove any references to your home folder (this can break Mezzanine)
while "." in sys.path:
    sys.path.remove(".")
while "" in sys.path:
    sys.path.remove("")

# specify django settings
os.environ['DJANGO_SETTINGS_MODULE'] = 'robot.settings'

# load default django wsgi app for Django >= 1.4
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

I have DEBUG = FALSE, so the PythonAnywhere server (nginx + uWSGI) must be serving the static files. I don't understand why I'm getting this 301 redirect error, which then appends a forward slash to my static file paths leading to a 404 error!

I've been banging my head against the wall for the past week trying to get the static files to work, but no progress so far. Everything works when I try to outsource static files through Amazon S3, but why is serving it on the same server with nginx + uWSGI not working for me? I have a "Beginners" account if this helps.

Help please!! :)

I followed this tutorial by the way: https://help.pythonanywhere.com/pages/HowtouseMezzanineonPythonAnywhere/

you need to also setup static file mappings on the webapps tab.

https://help.pythonanywhere.com/pages/StaticFiles/ and https://help.pythonanywhere.com/pages/DjangoStaticFiles

Unfortunately, I have already tried setting up static file mappings. No results for me. Here are my mappings:

Static:
/static/                     "/home/Robot/robot/static"

Media:
/media/                      "/home/Robot/robot/static/media"

Any clues or even pointers in the right direction?

Also, DEBUG=True works, the problem is when DEBUG=False!

Your account is imnorobo04, so I would expect your files to be in /home/imnorobo04, not /home/Robot

Sorry, I should've mentioned I changed the user name as an example for the post.

user = Robot in this example

Could it be that you have a trailing slash in your directories, but not in your file paths?

Okay, I figured it out!!

1) From your main project directory, run the following to have the latest static files copied into your STATIC_ROOT directory.

python managepy collectstatic

2) Cd into /var/www and run the following. This will copy all files from your STATIC_ROOT into /var/www/static

cp -r ~/your_project_name/static /var/www/static

3) Add the following static files mapping under the Web tab:

/static/         /var/www/static

4) Refresh the app. AHA! Now it works!!

** You can also bypass of this by setting your STATIC_ROOT = "/var/www/static" (after creating that directory, of course)

Apparently there's a special way of setting up Mezzanine on PythonAnywhere? You can find out more here if you're stuck in the same situation as me: https://www.pythonanywhere.com/forums/topic/251/

Hi, well, the important thing is that it works, so congratulations!

It does sound like a bit of a roundabout solution to me though. You should be able to get it working with a static files mapping that points from /static/ directly to /home/yourusername/your_project_name/static -- instructions here, if you fancy giving it a go, or if anyone else comes across this thread: https://help.pythonanywhere.com/pages/DjangoStaticFiles

harry,

unfortunately, those instructions do not work for me. I tried them many times with Django + Mezzanine apps with no luck. What worked was setting STATIC_ROOT = "/var/www/static". I still don't understand why this works though...