Django can't find staticfiles with Debug=False and Allowed_Hosts - django

Hi all I'm having trouble solving this issue: If I turn DEBUG to False, I can't run manage.py runserver:
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False
Then, let's say I add something to ALLOWED_HOSTS:
ALLOWED_HOSTS = ['*']
or
ALLOWED_HOSTS = ['localhost']
or
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
Now, I can do ´manage.py runserver´ but the staticfiles don't work. Weird.
If I turn DEBUG to True, then it works with ALLOWED_HOSTS set to nothing, to localhost or to *. So, I guess the problem has to do with DEBUG. I don't understand it.

In DEBUG mode, the Django development server handles serving static files for you. However, this is not best for production as it's much more inefficient than a true server. See here.
Serving the files
In addition to these configuration steps, you’ll also need to actually serve the static files.
During development, if you use django.contrib.staticfiles, this will be done automatically by runserver when DEBUG is set to True (see django.contrib.staticfiles.views.serve()).
This method is grossly inefficient and probably insecure, so it is unsuitable for production.
See Deploying static files for proper strategies to serve static files in production environments.
Check out here to learn out how to serve static files in production.
EDIT: Adding the following to answer #alejoss question about viewing error pages with DEBUG=True.
I added something like the following to my root urls.py file:
if settings.DEBUG:
urlpatterns += patterns(
'',
url(r'^400/$', TemplateView.as_view(template_name='400.html')),
url(r'^403/$', TemplateView.as_view(template_name='403.html')),
url(r'^404/$', 'django.views.defaults.page_not_found'),
url(r'^500/$', 'django.views.defaults.server_error'),
)
You might need to alter a bit (i.e., the 400 and 403 pages may need to be edited if your template names are different). Basically, this lets you visit http://localhost/400 to see your 400 error page, http://localhost/403 to see your 403 error page, and so on.

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

Okay Here's the very clean solution. you need to use
DEBUG = False
DEBUG_PROPAGATE_EXCEPTIONS = True
This way in your logs you can see what is then problem. Whitenoise returns 500 usually when It is missing some file.
You can see what is missing in you logs. In my case heroku logs were enough.
for more info: https://docs.djangoproject.com/en/2.0/ref/settings/#debug-propagate-exceptions

Related

Seeing Django debug 404 page despite having DEBUG = False

I have been following this tutorial along to deploy my first Django site and have successfully reached the section 'Configure Nginx to Proxy Pass to Gunicorn' which all seems to be working.
My problem is that, despite my settings.py file containing the following:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
I am still getting Django's debug=true 404 page with the following error:
"You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page."
I changed the file to DEBUG = False after completing the 'Configure Nginx to Proxy Pass to Gunicorn' step in the tutorial by pulling the change from my GitHub repository. Am I missing an additional step with Nginx in order to turn debug off and serve a standard 404 page?
Edit: It actually seems that any adjustments I make to the settings.py file in my repository, when pulled on to the server, don't have any effect. I commented out the whole settings.py file to see if it would break the webpage; nothing happened.
I'm guess that you does't restart web server after code editing. Try to restart your Gunicorn server, when you work with django runserver command it automatically restart web server on any change in code. Gunicorn dont do this by default, if you wanted that Gunicorn also restart server automatically, run it with --reload argument. But it dose not recommended into production

django DEBUG=False still runs in debug mode

I'm having issues setting my DEBUG = False on my deployed server (on heroku).
I don't believe I've seen this before, but setting debug to false is not getting rid of debug mode for my project. This means that when there are 500 errors it shows the error, and 404 errors are showing all my urls.
What's strange is that when i log into the server and run get the setting value from django.conf import settings settings.DEBUG it shows as False, which is what I set it to for the production server. TEMPLATE_DEBUG is also set to False.
I don't know I've ever seen this before where DEBUG = False but it's still acting in debug mode. Any ideas?
EDIT:
Thought I'd put this little note too because it's very common for people to be getting 500 or 400 errors when switching debug to False. I am not getting any errors, my project is just acting like it's in DEBUG mode.
# settings/dev.py
from .base import *
DEBUG = True
TEMPLATE_DEBUG = DEBUG
if not DEBUG:
ALLOWED_HOSTS = ['localhost']
SECRET_KEY = 'localsecret1234123412341234'
# settings/prod.py
from .base import *
import dj_database_url, os
DEBUG = os.environ.get("DEBUG", False)
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = ['mydomain.com']
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
DATABASES = {}
DATABASES['default'] = dj_database_url.config()
The root cause of issue - False translated to 'False' string not bool.
Used next solution (settings.py):
DEBUG = os.getenv('DEBUG', False) == 'True'
i.e.: in this case DEBUG will set to (bool) True, only if the environment variable is explicitly set to True or 'True'.
Good luck configuring! :)
As a note for others: I had the same problem; I configured my production website on a VM with gunicorn and nginx, following the tutorial for ubuntu 16.04 from the digital ocean documentation.
I wasn't able to turn off the debug mode, even when restarting the nginx systemd's service: the solution was to restart also the gunicorn service:
# systemctl restart nginx gunicorn
If somebody is using python-decouple for env variables and having trouble with DEBUG you have to use this line to retrieve booleans:
from decouple import config
DEBUG = config('DEBUG', default=False, cast=bool)
I'll put this as an actual answer for people that come after.
There are three main areas that this can happen, where 'this' is basically:
I've changed something in my settings, but it doesn't seem to be reflected in the operation of my app!
Server hasn't been reset after code changes made.
Local and Dev settings haven't overridden/or are overriding in unexpected ways
A local Environment Variable is overriding the attempt at hardcoding it
On Heroku, as in this example, Environment Variables are set this way. A more general guide to using them in Linux enviroments is available here.
Using an example from the question, you can see the environment variables being used in:
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
This uses the os library to go out to the system, and check for an environment variable called DJANGO_SECRET_KEY.
A better example is the:
DEBUG = os.environ.get("DEBUG", False)
This is good because it tries to get it from the environment, and if that fails, uses the second value in the tuple as the default: in this case, False.
During the course of debugging, you can hunt down your settings using printenv from the linux shell, which will print out all of the available EnvVars. If they're not there, you can set them in the format:
export DJANGO_SETTINGS_MODULE=mysite.settings
In this instance, it's probably better to unset the environment variable, rather than typecasting, as per this related answer.
This ended up being an issue with the config variable being "False" instead of False, and so debug wasn't properly set to the boolean value. Shoutout to #WithNail for helping get to the answer
DEBUG takes Boolean value.
The os.environ.get("DEBUG", False) returns string value.
All the string value while typecasting return True.
That's why the DEBUG is True.
print(bool(os.environ.get("DEBUG", False))) # output: True
print(bool("False")) # output: True
print(bool("")) # output: False
To solve issue in heroku don't set any value to config var. it will return null string and after typecasting it will return False:
When you use the module decouple (pip install python-decouple) make sure you cast DEBUG to a bool. Thus settings.py should have the following line:
from decouple import config
DEBUG = config('DEBUG', default=False, cast=bool)
where in the .env file
DEBUG = False # or True
I also experienced this problem as I was loading the debug setting from an environment variable DEBUG = os.environ.get('DEBUG_MODE')).
This set the DEBUG value as a string, not a boolean.
To fix this, I hardcoded DEBUG = False in my prod settings file.
I got the same error that OTREE_PRODUCTION=1 gives error 500 on Heroku. What I did is to make a new app (Note to change Heroku stack to make it compatible with your Python version) , upload codes to this new app, and set OTREE_PRODUCTION=1 for this new app.
I had the same issue & none of the solutions worked. My error stems from the the server configuration. I have multiple apps served by NGINX & GUNICORN. One of the apps is linked with the default server.
This means that any request not matching any of the IP:port listening pair server blocks is served by the default server. While debugging I happened to have set the settings.py of the app linked with the default server block to DEBUG=True & forgot to set it back to DEBUG=False.
So bringing settings.py of the default app's server block back to DEBUG=False, solved the issue.

Why does setting debug to false in django settings stop Heroku app from loading in development and production?

In my settings i have set DEBUG=False but this instead generated a 500 Error in both dev and production. so i looked around and came across this (Setting DEBUG = False causes 500 Error) and tried it out.
ALLOWED_HOSTS = ['www.heroku.com']
But this did not work, what am i not doing right? Am hosting with heroku
Your app is not hosted on www.heroku.com. Instead, try
ALLOWED_HOSTS = [".herokuapp.com"]
did you try
python manage.py collecstatic
?
you should review files directory becuase in prodhuction static files directory changes. heroku uses whitenouse

Django. Mezzanine new project not importing all files

I wanted to start playing around with Django again (I'm not an expert in Python/Django, but I can make nice things work tho). I used Mezzanine once just to see how it worked. The 'mezzanine-project myproject' command worked like a charm as I had a nice small app running quickly. So, today I downloaded the new Mezzanine 1.3 along with Django 1.4.3 and all its dependencies (pillow, pytz, html5lib, etc) and tried to create another project so I could now work on it in a more consistent manner for personal purposes.
For my surprise, when I ran the server, I got lots of 404 errors pointing to missing /static/ files. Also, after creating the database (with manage.py createdb command), the only thing created was the static folder containing only the pictures of the predefined gallery that come along with Mezzanine. Also, there is no Log in or signup buttons as well.
I've tried making a clean install of all Python and its site-packages with the same result. I also tried copying/pasting the folders containing missing files from the /site-packages/mezzanine folder into my project, but the result was just reducing the number of 404 messages.
I've been doing an extensive research on this issue (with no luck but maybe because of the release being recent?) and even trying to contact someone on the Mezzanine IRC channel with no success.
I hope I'm not missing something silly. Do I have to change anything (note that I'm ok with the old mezzanine default settings) in my settings.py or in a specific file before running manage.py createdb command?
For the record: before running createdb, The only thing I edited was settings.py and changed the database parameters to make it work with my MySQL Server and commenting the local_settings configuration as I do not need it.
Some parameters that could be of help:
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_ROOT, STATIC_URL.strip("/"))
By default, DEBUG is set to False in settings.py, and DEBUG is set to True in local_setting.py
Given that, if you just commented out importing local_settings.py, DEBUG would be False.
Django's development server won't serve static files when DEBUG is set to False, see the staticfiles section of the Django docs for more details.

Django: Override Debug=True from manage.py runserver command

Is there an easy way to tell Django's runserver to override a single variable in the settings.py file?
I would love to be able to call:
python manage.py runserver 0.0.0.0:8000 Debug=False
Any thoughts?
Motive: have a particular site where there are hundreds of database queries to show or save a particular page, I'd like to be able to turn off debug quickly without having to edit my settings file (which has the possibility of being forgotten).
I think you have two options
The simplest is probably a custom settings override, something like:
# no_debug_settings.py
# pull in the normal settings
from settings import *
# no debug for us
DEBUG = False
Now, when you want to start without debugging, you'd run:
python manage.py runserver --settings=no_debug_settings 0.0.0.0:8000
As an alternative, you could just customise your manage.py file. That imports settings, and passes it to the execute_manager. If you added some code between the import and the call, you could have it check for extra arguments and alter the settings as needed. It's a bit more fiddly and prone to break / be forgotten, so I'd suggest the override settings wrapper is probably your best way to go.
I edited my settings.py file with a conditional block, like this:
import os # If needed.
if os.environ.get('DJANGO_DEBUG'):
print("Debug is enabled.")
DEBUG = True
# When not specified, ALLOW_HOSTS defaults to:
# ALLOWED_HOSTS = ['localhost', '127.0.0.1', '[::1]']
else:
DEBUG = False
ALLOWED_HOSTS = ["*"]
Then, run your server by passing the environmental variable DJANGO_DEBUG=1. You can name the variable anything you want so long as you are consistent:
DJANGO_DEBUG=1 python -Wall manage.py runserver
Omit that environmental variable when calling manage.py to disable debug (because setting it to any value, including 0 will still make it true to the Python code.)
Update: A commenter stated that the ALLOWED_HOSTS directive is ignored when DEBUG is True. This is only true in older versions of Django. The current behavior is to honor ALLOWED_HOSTS or default to localhost addresses if it isn't specified when DEBUG is enabled. My answer is updated to reflect this as a minor correction.
This is sourced from the Django documentation:
When DEBUG is True and ALLOWED_HOSTS is empty, the host is
validated against ['localhost', '127.0.0.1', '[::1]']
Additionally, it states that the behavior your comment on is now outdated in a few major version lines:
In older versions, ALLOWED_HOSTS wasn’t checked if DEBUG=True.
This was also changed in Django 1.10.3, 1.9.11, and 1.8.16 to prevent a
DNS rebinding attack.