Django: serving static file on debug=false

21,866

Solution 1

as you can see in the warning box in the docs, in production (i.e. with debug=False) you should be using your web server to serve static files, not django. For that reason, staticfiles will refuse to serve your assets if debug=False.

Solution 2

in settings.py::

if DEBUG: 
   STATIC_ROOT = os.path.join(BASE_DIR, '/static')
else:
   STATIC_ROOT = os.path.join(BASE_DIR, 'static') 

and in urls.py add

import django.views.static
urlpatterns += [
   url(r'^static/(?P<path>.*)$', django.views.static.serve, {'document_root': settings.STATIC_ROOT, 'show_indexes': settings.DEBUG})
]

Solution 3

I'm using the code below in my root urls.py. You need to set FORCE_SERVE_STATIC to True in settings file if you want static and media to be served by django development server. And don't forget to run collectstatic command to update your static files.

from django.conf.urls.static import static
from django.conf import settings

<...>

if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
elif getattr(settings, 'FORCE_SERVE_STATIC', False):
    settings.DEBUG = True
    urlpatterns += static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(
        settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    settings.DEBUG = False

Solution 4

This is a late answer but may be this will help someone. There is an extra option to be used with runserver command which force Django to serve static files even when DEBUG=False

python manage.py runserver --insecure

Django docs ref: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#cmdoption-runserver-insecure

Solution 5

In your urls.py file:

add this line

from django.views.static import serve

add those two urls in urlpatterns:

url(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),
url(r'^static/(?P<path>.*)$', serve,{'document_root': settings.STATIC_ROOT}),
Share:
21,866
Neara
Author by

Neara

Updated on July 11, 2022

Comments

  • Neara
    Neara almost 2 years

    I know this question was asked many times, but none of the answers i found and tried helped me.

    Those are my static files settings:

    STATIC_ROOT = os.path.abspath(SETTINGS_PATH+'/staticfiles/')
    
    # URL prefix for static files.
    # Example: "http://media.lawrence.com/static/"
    STATIC_URL = '/staticfiles/'
    
    # Additional locations of static files
    STATICFILES_DIRS = (
        # Put strings here, like "/home/html/static" or "C:/www/django/static".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.
        os.path.join(os.path.dirname(__file__), 'static'),
        )
    
    # List of finder classes that know how to find static files in
    # various locations.
    STATICFILES_FINDERS = (
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    #    'django.contrib.staticfiles.finders.DefaultStorageFinder',
    ) 
    

    And in myapp/urls.py:

    from django.conf.urls import patterns, include, url
    from django.conf import settings
    from django.contrib import admin
    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
    
    admin.autodiscover()
    
    urlpatterns = patterns('',
        # urls
    )
    
    urlpatterns += staticfiles_urlpatterns()
    

    Collectstatic copies all files to staticfiles/ as it should and i get 404 on all static files.

    I also tried this in urls.py:

    if not settings.DEBUG:
        urlpatterns += patterns('',
            url(r'^staticfiles/(?P<path>.*)$', 'django.views.static.serve',
                {'document_root': settings.STATIC_ROOT}),
        )
    

    This gives me following kind of errors:

    Resource interpreted as Stylesheet but transferred with MIME type text/html:  "http://localhost:8000/?next=/staticfiles/css/bootstrap.css". localhost:11
    Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:8000/?next=/staticfiles/css/style.css". localhost:12
    Resource interpreted as Script but transferred with MIME type text/html: "http://localhost:8000/?next=/staticfiles/js/bootstrap.js". localhost:79
    Resource interpreted as Script but transferred with MIME type text/html: "http://localhost:8000/?next=/staticfiles/js/login.js". 
    

    I can't see what's wrong with my settings. Any ideas are most welcome.

  • Neara
    Neara over 11 years
    I set debug=false to recreate a problem i have on prod server. This app is deployed on Heroku. And i have same problem there, but i use second version of urls.py. Everything worked for a time, but no more. I intend to use S3 asap, but for now i need it to work w.o. Any ideas how to change the settings to make it work?
  • winwaed
    winwaed over 10 years
    +1 Thanks @second - that appear to be my problem here. Preparing for deployment and running locally. Another deployment wrinkle!
  • Saher Ahwal
    Saher Ahwal over 7 years
    Hey so the django folks say that the original method when debug is true is "This method is grossly inefficient and probably insecure, so it is unsuitable for production." here: docs.djangoproject.com/en/dev/howto/static-files/…. Is what you are doing a workaround or the right thing to do?
  • Saher Ahwal
    Saher Ahwal over 7 years
    Is the other answer by Angel above correct or a workaround?
  • second
    second over 7 years
    i would not use django staticfiles in production. if you need a pure python solution (e.g. for heroku), consider whitenoise
  • OrangeDog
    OrangeDog over 6 years
    Minor rant at Django: I don't want to use staticfiles in production, I just want to use it development without having the debug error pages etc.
  • Mehran Nouri
    Mehran Nouri almost 5 years
    Why I am getting this error? Directory indexes are not allowed here
  • rubmz
    rubmz almost 5 years
    This is the right solution for anyone wishing just to develop django site but make it run a little bit faster. It's the right way also because it is only a flag, and would/should probably not be moved on to production environment.
  • wishmaster
    wishmaster over 3 years
    for people using Django ver 2.1 + STATIC_ROOT = 'static'