Why does DEBUG=False setting make my django Static Files Access fail?

DjangoDjango ViewsDjango Staticfiles

Django Problem Overview


Am building an app using Django as my workhorse. All has been well so far - specified db settings, configured static directories, urls, views etc. But trouble started sneaking in the moment I wanted to render my own beautiful and custom 404.html and 500.html pages.

I read the docs on custom error handling, and set necessary configurations in UrlsConf, created corresponding views and added the 404.html and the 500.html to my app's template directory (specified in the settings.py too).

But the docs say you can actually view custom error views until Debug is Off, so I did turn it off to test my stuff, and that's when stuff goes berserk!

Not only do I fail to view the custom 404.html (actually, it loads, but because my error pages each contain a graphic error message -as some nice image), the source of the error page loads, but nothing else loads! Not even linked CSS or Javascript!

Generally, once I set DEBUG = False, all views will load, but any linked content (CSS, Javascript, Images, etc) wont load! What's happening? Is there something am missing, concerning static files and the DEBUG setting?

Django Solutions


Solution 1 - Django

If you still need to server static locally (e.g. for testing without debug) you can run devserver in insecure mode:

manage.py runserver --insecure

Solution 2 - Django

With debug turned off Django won't handle static files for you any more - your production web server (Apache or something) should take care of that.

Solution 3 - Django

In urls.py I added 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}), 

and both static and media files were accesible when DEBUG=FALSE.
Hope it helps :)

Solution 4 - Django

You can use WhiteNoise to serve static files in production.

Install:

pip install WhiteNoise==2.0.6

And change your wsgi.py file to this:

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

And you're good to go!

Credit to Handlebar Creative Blog.

BUT, it's really not recommended serving static files this way in production. Your production web server(like nginx) should take care of that.

Solution 5 - Django

Johnny's answer is great, but still didn't work for me just by adding those lines described there. Based on that answer, the steps that actually worked for me where:

  1. Install WhiteNoise as described:

    pip install WhiteNoise
    
  2. Create the STATIC_ROOT variable and add WhiteNoise to your MIDDLEWARE variable in settings.py:

    #settings.py
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'whitenoise.middleware.WhiteNoiseMiddleware', #add whitenoise
        'django.contrib.sessions.middleware.SessionMiddleware',
        ...
    ]
    
    #...
    
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') ##specify static root
    
  3. Then, modify your wsgi.py file as explained in Johnny's answer:

    #wsgi.py
    from django.core.wsgi import get_wsgi_application
    from whitenoise.django import DjangoWhiteNoise
    
    application = get_wsgi_application()
    application = DjangoWhiteNoise(application)
    
  4. After that, deploy your changes to your server (with git or whatever you use).

  5. Finally, run the collectstatic option from your manage.py on your server. This will copy all files from your static folders into the STATIC_ROOT directory we specified before:

    $ python manage.py collectstatic
    

You will now see a new folder named staticfiles that contains such elements.

After following these steps you can now run your server and will be able to see your static files while in Production mode.

Update: In case you had version < 4 the changelog indicates that it's no longer necessary to declare the WSGI_APPLICATION = 'projectName.wsgi.application' on your settings.py file.

Solution 6 - Django

If you are using the static serve view in development, you have to have DEBUG = True :

> Warning > > This will only work if DEBUG is True. > > That's because this view is grossly > inefficient and probably insecure. > This is only intended for local > development, and should never be used > in production.

Docs: serving static files in developent

EDIT: You could add some urls just to test your 404 and 500 templates, just use the generic view direct_to_template in your urls.

from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
    ('^404testing/$', direct_to_template, {'template': '404.html'})
)

Solution 7 - Django

You actually can serve static files in a production Django app, securely and without DEBUG=True.

Rather than using Django itself, use dj_static in your WSGI file (github):

requirements.txt:

...
dj-static==0.0.6

YOURAPP/settings.py:

...
STATIC_ROOT = 'staticdir'
STATIC_URL = '/staticpath/'

YOURAPP/wsgi.py:

...
from django.core.wsgi import get_wsgi_application
from dj_static import Cling

application = Cling(get_wsgi_application())

Solution 8 - Django

You can debug this in many different ways. Here's my approach.

localsettings.py:

DEBUG = False
DEBUG404 = True

urls.py:

from django.conf import settings
import os

if settings.DEBUG404:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', 'django.views.static.serve',
         {'document_root': os.path.join(os.path.dirname(__file__), 'static')} ),
    )

Be sure to read the docs ;)

https://docs.djangoproject.com/en/2.0/howto/static-files/#limiting-use-to-debug-true

Solution 9 - Django

For last versions of Django please look at the answer here: https://stackoverflow.com/a/7639983/6180987

For django version below 1.10 the solution should work:

Just open your project urls.py, then find this if statement.

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

You can change settings.DEBUG on True and it will work always. But if your project is a something serious then you should to think about other solutions mentioned above.

if True:
    urlpatterns += patterns(
        'django.views.static',
        (r'^media/(?P<path>.*)','serve',{'document_root': settings.MEDIA_ROOT}), )

In django 1.10 you can write so:

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

Solution 10 - Django

This is Exactly you must type on terminal to run your project without DEBUG = TRUE and then you see all assets (static) file is loading correctly On local server .

python manage.py runserver --insecure 

--insecure : it means you can run server without security mode

Solution 11 - Django

Ultimate solution:-
So basically when you make debug = False, Django doesn't want to take care of your static files.
So we want something that can take care of our files.
The answer is whitenoise.

  1. pip install whitenoise in your environment

  2. Add 'whitenoise.middleware.WhiteNoiseMiddleware' in your middleware list in settings.py.

    This should be added just below the 'django.middleware.security.SecurityMiddleware' and above all the remaining middleware. So that your middleware list will look like this:-

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'whitenoise.middleware.WhiteNoiseMiddleware',
        # add it exactlyhere
        'django.contrib.sessions.middleware.SessionMiddleware',
        '...'
    ]
    
  3. Add 'whitenoise.runserver_nostatic' on top of your installed apps So that your installed apps list will look like this:-

    INSTALLED_APPS = [
        'whitenoise.runserver_nostatic',
        'django.contrib.admin',
        'django.contrib.auth',
        '...'
    ]
    

Done, you will be able to serve static files in production now!!

Solution 12 - Django

I agree with Marek Sapkota answer; But you can still use django URFConf to reallocate the url, if static file is requested.

Step 1: Define a STATIC_ROOT path in settings.py

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

Step 2: Then collect the static files

$ python manage.py collectstatic

Step 3: Now define your URLConf that if static is in the beginning of url, access files from the static folder staticfiles. NOTE: This is your project's urls.py file:

from django.urls import re_path
from django.views.static import serve

urlpattern += [
  re_path(r'^static/(?:.*)$', serve, {'document_root': settings.STATIC_ROOT, })
]

Solution 13 - Django

when i make DEBUG = True my static are doesn't work.

if i run my project in python manage.py runserver --insecure . By this i got my static as well.

Solution 1:

python manage.py runserver --insecure

Solution 2:

But I Need Permanent Solution. then i install pip install dj-static==0.0.6 and add some code to my wsgi.py file:

from django.core.wsgi import get_wsgi_application
from dj_static import Cling

application = Cling(get_wsgi_application())

and then i added some in setting.py:

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

Solution 14 - Django

From here I took help by mixing a few answers. Here, I am adding my whole parts. [I am doing this for a beginners help and for my future use as well]

Well at first the question is why Debug=False needed! I put my project in AWS and it was being connection timeout after few hours because of memory leaking. At first I thought for celery. [of course I am just a beginner] Then I put DEBUG=False from DEBUG=True As we can see the security warning in settings.py

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

Once I did that my staticfiles were not loading successfully in webpages. Then I searched everywhere and at first tried from here the --insecure command to runserver.

python manage.py runserver --insecure

Which is successful but I don't want the insecure mode in my project when it is in production. And as the proper solution [according to me] I followed the steps below.

At first, I correct the static URL,root, and dir in settings.py

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

Then collect the static files by command

python manage.py collectstatic

Now the second step, [which also provided here] At first install whitenoise in your project directory in the command line

pip install whitenoise

Then Add 'whitenoise.middleware.WhiteNoiseMiddleware' in your middleware list in settings.py.

This should be added just below the 'django.middleware.security.SecurityMiddleware' and above all the remaining middleware. So that your middleware list will look like this:-

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware', #after this line
    'whitenoise.middleware.WhiteNoiseMiddleware', #add it exactlyhere
    'django.contrib.sessions.middleware.SessionMiddleware', #before this
    '...'
]

Add 'whitenoise.runserver_nostatic' on top of your installed apps So that your installed apps list will look like this:-

INSTALLED_APPS = [
    'whitenoise.runserver_nostatic',
    'django.contrib.admin',
    'django.contrib.auth',
    '...'
]

Done, you will be able to serve static files in production now!! [I did on my local environment as well]

Just use the runserver command as always no insecure or anything needed.

python manage.py runserver

Boom!!! It's working for me. Hahaha. I know kinda childish nature but I am so happy now.

Thanks to everyone who provided answers here and help my work.

Solution 15 - Django

This is normal and intended behavior.

Warning

This will only work if DEBUG is True.  
you can actually view custom error views until Debug is Off  

If Django is just reading from the filesystem and sending out a file, then it has no advantage over a normal web server, all web servers are capable to server the files on it's own.

Furthermore, if you serve static files with Django, you will keep the Python process busy for the duration of the request and it will be unable to serve the dynamic requests to which it is more suited.

For these reasons, the Django static view is designed only for use during development and will not work if your DEBUG setting is False.

Since during development we only usually have one person accessing the site at a time (the developer), Django is fine to serve static files.

Solution 16 - Django

Support for string view arguments to url() is deprecated and will be removed in Django 1.10

My solution is just small correction to Conrado solution above.

from django.conf import settings
import os
from django.views.static import serve as staticserve

if settings.DEBUG404:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', staticserve,
            {'document_root': os.path.join(os.path.dirname(__file__), 'static')} ),
        )

Solution 17 - Django

I did the following changes to my project/urls.py and it worked for me

Add this line : from django.conf.urls import url

and add : url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT, }), in urlpatterns.

Solution 18 - Django

nginx,settings and url configs

If you're on linux this may help.

nginx file

your_machn:/#vim etc/nginx/sites-available/nginxfile

server {
    server_name xyz.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /var/www/your_prj;
    }

    location /media/ {
        root /var/www/your_prj;
    }
...........
......
}

urls.py

.........
   .....
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('test/', test_viewset.TestServer_View.as_view()),
        path('api/private/', include(router_admin.urls)),
        path('api/public/', include(router_public.urls)),    
        ]
    
    if settings.DEBUG:
        import debug_toolbar
        urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
        urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

settings.py

.....
........
STATIC_URL = '/static/'
MEDIA_URL = '/media/'

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

Ensure to run:

(venv)yourPrj$ ./manage.py collectstatic
yourSys# systemctrl daemon-reload

Solution 19 - Django

Although it's not safest, but you can change in the source code. navigate to Python/2.7/site-packages/django/conf/urls/static.py

Then edit like following:

if settings.DEBUG or (prefix and '://' in prefix):

So then if settings.debug==False it won't effect on the code, also after running try python manage.py runserver --runserver to run static files.

NOTE: Information should only be used for testing only

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJWLView Question on Stackoverflow
Solution 1 - DjangoDmitry ShevchenkoView Answer on Stackoverflow
Solution 2 - DjangoMarek SapotaView Answer on Stackoverflow
Solution 3 - DjangostathoulaView Answer on Stackoverflow
Solution 4 - DjangoJohnny ZhaoView Answer on Stackoverflow
Solution 5 - DjangoDarkCygnusView Answer on Stackoverflow
Solution 6 - Djangoj_sykView Answer on Stackoverflow
Solution 7 - DjangoRobin WinslowView Answer on Stackoverflow
Solution 8 - DjangoConradoView Answer on Stackoverflow
Solution 9 - DjangoSergey LuchkoView Answer on Stackoverflow
Solution 10 - DjangoAlireza AtashnejadView Answer on Stackoverflow
Solution 11 - DjangoChhinnaView Answer on Stackoverflow
Solution 12 - DjangoPaxPrzView Answer on Stackoverflow
Solution 13 - DjangoMd Abdur Rahman ChowdhuryView Answer on Stackoverflow
Solution 14 - DjangoAnnyView Answer on Stackoverflow
Solution 15 - DjangoPiyush PranjalView Answer on Stackoverflow
Solution 16 - Djangobe_good_do_goodView Answer on Stackoverflow
Solution 17 - DjangoNamrata SharmaView Answer on Stackoverflow
Solution 18 - Django7guyoView Answer on Stackoverflow
Solution 19 - DjangoNatutoView Answer on Stackoverflow