将DEBUG设置为False会导致500错误。

327
一旦我更改了DEBUG = False,我的网站会生成500错误(使用wsgi和manage.py runserver),而且在Apache错误日志中没有错误信息。当我将debug更改为True时,它会正常运行。
我正在使用Django 1.5和Python 2.7.3这里是Apache访问日志,并且在Apache错误日志中没有任何日志。
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET / HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"

这是我的设置文件:

import os.path    
DEBUG = False 
#TEMPLATE_DEBUG = DEBUG

HERE = os.path.dirname(__file__)
ADMINS = (
    ('admin', 'xyzadmin@qq.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'zdm',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': 'passwd',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
#STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
#STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')
S= os.path.join(HERE, 'static').replace('\\','/')

# 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.
    '/home/zdm/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',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '9a7!^gp8ojyk-^^d@*whuw!0rml+r+uaie4ur$(do9zz_6!hy0'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'zdm.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'zdm.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/zdm/templates',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'zdm',
    'portal',
    'admin',
    'tagging',
)

是的,我已经在我的模板目录中添加了403和404 500 HTML文件。 - zhiguo.wang
1
你的项目中是否已经放置了500.html、404.html和403.html文件?我记得曾经在一个部署的项目中遇到过这样的问题,那个项目的根目录下没有这些文件。 - esse
在我的问题中添加一些访问日志。谢谢。 - zhiguo.wang
102
既然你的SECRET_KEY已经公开,你可能想要更改它了... - ashastral
1
这并不适用于所有人。如在https://dev59.com/PWUp5IYBdhLWcg3wrI7T#37218484中所示,可能会有许多原因导致此问题发生。通过一些简单的记录,您可以在没有猜测的情况下找出原因。 - Rob
显示剩余2条评论
33个回答

426
Django 1.5引入了allowed hosts setting,出于安全原因这是必须的。使用Django 1.5创建的设置文件中有这个新的部分,需要添加:
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.9/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []

将您的主机添加在此处,例如['www.beta800.net']['*']进行快速测试,但不要在生产环境中使用['*']

34
哇,这个问题真的困扰了我们。很遗憾,这个设置被埋藏在文档中。如果DEBUG = False,我们的生产网站将无法正常工作。感谢您指出这一点! - shreddd
4
关于引入此设置的安全问题,请参见 实用的 HTTP Host 头攻击。这篇文章肯定会让你相信在生产环境中不要使用 ['*'] - gertvdijk
4
很烦人,他们甚至没有将其作为默认值放入settings.py中,或许可以附上一条解释性注释... - hwjp
7
有时候我会想,为什么 Django 越来越令人沮丧!那些开发者肯定比我优秀得多,但我真的不明白为什么要在应用层面上“修复”漏洞,而不是采取真正干净的方式,在服务器上做出配置。同样适用于“模板缓存”和“持久连接”……这些毫无用处的代码永远不会在一个严肃的网站上使用;它们被宣传成编程的圣杯!也许只有我觉得如此,以前我也曾犯过错误! - StefanNch
3
没关系,找到问题了。它与django-pipeline在静态文件还没有被收集时的行为有关。作为一般提示,将断点放在Django的handle_uncaught_exception方法中将帮助您弄清楚这里发生了什么。 - Pieter
显示剩余8条评论

82

我知道这有点晚了,但我通过搜索错误代码为500和 DEBUG=False 才找到了这里。在我的情况下,最终的问题确实是 ALLOWED_HOSTS 但我使用 os.environ.get('variable') 来填充主机,我没有注意到这一点,直到开启日志记录。您可以使用以下内容将所有错误记录到文件中,即使 DEBUG=False:

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'mysite.log',
            'formatter': 'verbose'
        },
    },
    'loggers': {
        'django': {
            'handlers':['file'],
            'propagate': True,
            'level':'DEBUG',
        },
        'MYAPP': {
            'handlers': ['file'],
            'level': 'DEBUG',
        },
    }
}

28
这应该是被接受的答案。在使用生产设置后,直接询问框架本身出了什么问题要比猜测更有用。 - Stefan Dragnev
4
确实,这不是可以在黑暗中漫游的事情。只需查看使用此方法通常会看到的错误消息即可。在我的情况下,我的应用程序正在寻找设置文件settings.py中缺少的其他设置。我所需要的就是记录以跟踪此问题。一个重要的提示:我按照文档示例添加了路径 /path/to/my/django/ 到 'mysite.log' 前面。 https://docs.djangoproject.com/en/1.10/topics/logging/#examples - Rob
4
我花了几个小时寻找解决办法,但毫无用处。根据这个答案,只需使用日志记录,你就可以解决问题了,这是最佳答案。感谢楼主! - Stack
6
谢谢!这解决了我的错误。原来我需要运行collectstatic来收集包中的一些静态资源。 - themessup
1
@Gorgonzola 如果你的团队中有系统管理员,请联系他们。他们最擅长解决权限被拒绝的问题。就像我说的,有很多事情可能会阻碍进展。 - squareborg
显示剩余6条评论

62
我最近在Django 2.0中遇到了同样的问题。通过设置DEBUG_PROPAGATE_EXCEPTIONS = True,我能够找出问题所在。请看这里:https://docs.djangoproject.com/en/2.0/ref/settings/#debug-propagate-exceptions 在我的情况下,错误是ValueError: Missing staticfiles manifest entry for 'admin/css/base.css'。我通过本地运行python manage.py collectstatic来解决了这个问题。

我遇到了同样的问题,但是collectstatic并没有解决它。你是否遇到了“无法访问”的错误?如果是这样,你是如何解决的? - Kavi Vaidya
6
为什么这个排名如此靠后?无论错误的原因是什么,这都有所帮助。 - TheHippo
4
这应该是回答“如何在Django中调试500错误”的问题: - Dt23
请注意,根据答案中链接的文档,不应在生产环境中启用此功能(除非完全理解其作用)。 - Tyler A.

27

在我的情况下,认真阅读第三方应用程序的文档为我节省了不少麻烦。

罪魁祸首?django_compressor

我有...

{% load compress %}
{% compress css %}
 ... css files linked here ..
{% endcompress %}

DEBUG = True总是给我返回500。为了解决这个问题,我需要在我的设置中添加一行代码。

COMPRESS_ENABLED = os.environ.get('COMPRESS_ENABLED', False)

谢谢,那就是它不能为我工作的原因,但是那行不会禁用django_compressor的功能吗? - Fanckush
1
@Fanckush 不用担心。并没有伤害。 https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_ENABLED 压缩器仍然可以完美地完成其工作!只需压缩您的所有静态资源(如css),因此该设置对您已经压缩的资产毫无用处。 - KhoPhi

19

2019年中期,我在使用Django开发了几年后遇到了这个错误。整整一个晚上都困扰着我!它不是"not allowed host"(应该会抛出400错误),其他所有的方面都没有问题。最终,我进行了一些错误记录,才发现一些缺失或混乱的静态文件清单(在collectstatic后)破坏了设置。长话短说,对于那些被卡住了,并且正在使用WHITENOISE或具有CACHE(清单静态文件)的DJANGO STATICFILE后端的人们,也许这就是为你们准备的。

  1. 确保您设置了所有内容(就像我为WHITENOISE后端所做的那样...无论如何,仍然可以阅读DJANGO后端) http://whitenoise.evans.io/en/stable/django.html

  2. 如果错误代码500仍然使您失败,请注意您的settings.STATICFILES_STORAGE。

将其设置为以下之一(对于具有压缩的WHITENOISE后端)

STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'

或者(保持为Django默认值)

STATICFILES_STORAGE = django.contrib.staticfiles.storage.StaticFilesStorage

总之,问题似乎源于这个白噪声缓存+压缩后端——>

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
或者使用 Django 自己的缓存后端 -->
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

...... 对我来说效果不是很好,因为我的CSS在引用其他来源时可能会在collectstatic /后端缓存期间混淆。这个问题在http://whitenoise.evans.io/en/stable/django.html#storage-troubleshoot中也有可能被强调。


3
对我而言,使用 whitenoise.storage.CompressedStaticFilesStorage 取得了良好的效果。 - xax
虽然我还有其他一些事情需要弄清楚和修复,但这似乎是我的答案。总有一天我会完全理解静态文件在生产中的工作原理。我不知道为什么它让我感到如此困惑。 - pspahn
1
谢谢!这让我疯了。这个错误只会在远程环境中,且 DEBUG 设置为 False 时发生。 - pfcodes

13

在Django 1.5中,如果DEBUG = False,则需要配置ALLOWED_HOSTS,并添加不带端口号的域名。例如:

ALLOWED_HOSTS = ['localhost']

由于某种原因,使用“localhost”对我没有起作用。我不得不使用IP“127.0.0.1”。如果你很紧张,只想让它工作,我也能使用“*”。然而,我不建议在生产环境中这样做。OSX运行Django 1.4.20 - Blake Petersen

13

您还必须检查您的URL是否到位。当 DEBUG 设置为 False 时,所有没有结尾 / 的URL都会被视为错误,而当您将 DEBUG = True 时,Django 将在缺少 / 的情况下添加它。因此,请确保所有链接在任何地方都以斜线结束。


3
只需使用反转和 URL 标签,您就可以完成。 - maazza
DEBUG=False设置可以揭示导入错误:https://dev59.com/yYPba4cB1Zd3GeqPnx2B#25754343 - ecoe
甚至包括 js 和 css 资源的链接? - amchugh89
@amchugh89:不,只是“Django”网址。 - webzy
1
我的问题是 whitenoise 找不到一些图片并抛出 ValueError。我也找不到它,但不知道如何告诉 whitenoise 不要查找它。因此,我关闭了 whitenoise,使用 django static serve,现在可以在 prod 中运行 debug=False。显然不是理想的解决方案 :( - amchugh89

9

补充主要答案
在开发和生产环境之间切换时,更改settings.py中的ALLOWED_HOSTS和DEBUG全局常量是很麻烦的。 我使用以下代码自动设置这些设置:

import socket

if socket.gethostname() == "server_name":
    DEBUG = False
    ALLOWED_HOSTS = [".your_domain_name.com",]
    ...
else:
    DEBUG = True
    ALLOWED_HOSTS = ["localhost", "127.0.0.1",]
    ...

如果您使用macOS,您可以编写更通用的代码:
if socket.gethostname().endswith(".local"): # True in your local computer
    DEBUG = True
    ALLOWED_HOSTS = ["localhost", "127.0.0.1",]
else:
    ...

8

我正在搜索和测试与此问题相关的更多内容,我意识到在settings.py中指定的静态文件目录可能是导致此问题的原因,所以首先,我们需要运行以下命令:

python manage.py collectstatic

在settings.py中,代码应该类似于这样:
STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

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

8

值得一提的是,我只有在某些页面上使用DEBUG = False时才会遇到500错误。通过pdb回溯异常发现缺少某些资产(我怀疑{% static ... %}模板标签是导致500的罪魁祸首。


1
这也是我的问题,自定义404页面引用的基本模板使用了静态标签,但在顶部没有包含{% load static %}。我没有在其他地方注意到它,因为我的其他模板都有这一行,但将其放在基础模板中是有意义的,因为它涉及到各个静态文件。 - krischan
2
这里有相同的解决方案 - 我使用了 static 来包含一个不存在的 CSS 文件。 - Phil Gyford
这是我遇到过最搞笑的问题。连续向我提问了2个小时。 - Dekriel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接