为什么DEBUG=False设置使我的django静态文件访问失败?

我建立一个应用程序使用Django作为我的主力。到目前为止,一切都很好-指定的数据库设置,配置的静态目录,url,视图等。但是当我想要渲染自己漂亮的自定义404.html和500.html页面时,麻烦就来了。

我阅读了关于自定义错误处理的文档,并在UrlsConf中设置了必要的配置,创建了相应的视图,并将404.html和500.html添加到我的应用程序的模板目录(在settings.py中也指定了)。

但是文档说you can actually view custom error views until Debug is Off,所以我确实关闭了它来测试我的东西,而那就是东西疯狂的时候!

我不仅无法查看自定义404.html(实际上,它加载,但因为我的错误页面每个包含一个图形错误消息-作为一些漂亮的图像),错误页面的源加载,但没有其他加载!甚至没有链接CSS或Javascript!

通常,一旦我设置DEBUG = False,所有的视图将加载,但任何链接的内容(CSS, Javascript,图像等)不会加载!发生什么事情了?关于静态文件和DEBUG设置,是否缺少一些东西?

187196 次浏览

如果你在开发中使用静态服务视图,你必须有DEBUG = True:

警告

这只在DEBUG为True时有效。

这是因为这个观点是粗暴的 效率低下,而且可能不安全。 这只适用于本地 开发,绝不应该使用 在生产。< / p >

Docs:在开发中提供静态文件

编辑:你可以添加一些url只是为了测试你的404和500模板,只是在你的url中使用通用视图direct_to_template。

from django.views.generic.simple import direct_to_template


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

关闭调试后,Django将不再为你处理静态文件——你的生产web服务器(Apache或其他)应该处理这些。

您可以用许多不同的方式调试它。这是我的方法。

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')} ),
)

请务必阅读文档;)

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

如果你仍然需要服务器静态本地(例如测试没有调试),你可以在不安全模式下运行devserver:

manage.py runserver --insecure

实际上,你可以在Django生产应用程序中提供静态文件,而且不需要DEBUG=True

不要使用Django本身,在你的WSGI文件中使用dj_static (github):

让:

...
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())

对url()的字符串视图参数的支持已弃用,并将在Django 1.10中被移除

我的解决方案只是上面孔拉多解决方案的小修正。

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')} ),
)

可以使用WhiteNoise在生产环境中提供静态文件。

安装:

pip install WhiteNoise==2.0.6

并将你的wsgi.py文件更改为:

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


application = get_wsgi_application()
application = DjangoWhiteNoise(application)

你可以开始了!

功劳归创意博客

但是,真的不建议在生产环境中以这种方式提供静态文件。你的生产web服务器(比如nginx)应该处理这个问题。

对于Django的最新版本,请查看这里的答案:https://stackoverflow.com/a/7639983/6180987

对于1.10以下的django版本解决方案应该工作:

只要打开你的项目urls.py,然后找到这个if语句。

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

您可以更改设置。DEBUG设为True,它将始终工作。但如果你的项目是一个严重的问题,那么你应该考虑上面提到的其他解决方案。

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

在django 1.10中,你可以这样写:

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

虽然这不是最安全的,但您可以在源代码中进行更改。导航到Python/2.7/site-packages/django/conf/urls/static.py

然后像下面这样编辑:

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

因此,如果settings.debug==False不会对代码产生影响,同样在运行后尝试python manage.py runserver --runserver来运行静态文件。

请注意:信息只能用于测试

在urls.py中,我添加了这一行:

from django.views.static import serve

在urlpatterns中添加这两个url:

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

,当DEBUG=FALSE时静态文件和媒体文件都是可访问的 希望它有助于:)

约翰尼的回答是伟大的,但仍然没有为我只是添加那些行描述那里。根据这个答案,对我有效的步骤是:

  1. 安装WhiteNoise如下所示:

    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
    

    您现在将看到一个名为staticfiles的新文件夹,其中包含这些元素。< / p >

在遵循这些步骤之后,您现在可以运行您的服务器,并且能够在生产模式下看到您的静态文件。

更新:如果你有版本<4 . 更新日志表示不再需要在你的settings.py文件上声明WSGI_APPLICATION = 'projectName.wsgi.application'

我对我的project/urls.py做了以下更改,它为我工作

添加这一行: 导入url

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

这是你必须在终端上键入的,以运行你的项目,没有DEBUG = TRUE 然后你会看到所有的资产(静态)文件在本地服务器上正确加载

python manage.py runserver --insecure

--insecure:这意味着你可以在没有安全模式的情况下运行服务器

我同意Marek Sapkota的回答;但是你仍然可以使用django URFConf来重新分配url,如果静态文件被请求的话。

步骤1:在settings.py中定义STATIC_ROOT路径

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

步骤2:然后收集静态文件

$ python manage.py collectstatic

步骤3:现在定义你的URLConf,如果static在url的开头,从静态文件夹staticfiles中访问文件。注意:这是你项目的urls.py文件:

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


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

Nginx,设置和url配置

如果你在linux上,这可能会有帮助。

nginx文件

your_machn: / # vim等/ nginx /网站/ 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')
.....
....

确保运行:

(venv)yourPrj$ ./manage.py collectstatic
yourSys# systemctrl daemon-reload
< p >终极解决方案:-
所以当你设置debug = False时,Django不会关心你的静态文件。
所以我们想要一些可以处理我们文件的东西。
答案是白噪声。

  1. PIP安装白噪音在你的环境中

  2. 在settings.py的中间件列表中添加“whitenoise.middleware.WhiteNoiseMiddleware”

    它应该添加在“django.middleware.security.SecurityMiddleware”下面,所有剩余的中间件之上。这样你的中间件列表看起来就像这样:-

    MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # add it exactlyhere
    'django.contrib.sessions.middleware.SessionMiddleware',
    '...'
    ]
    
  3. 在你安装的应用程序顶部添加“whitenoise.runserver_nostatic” 因此,你安装的应用程序列表将看起来像这样:-

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

完成后,您现在就可以在生产环境中提供静态文件了!!

这是正常且有意为之的行为。

Warning


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

如果Django只是从文件系统中读取并发送一个文件,那么它与普通的web服务器相比没有任何优势,所有的web服务器都能够自己提供文件。

此外,如果你用Django提供静态文件,你会让Python进程在请求期间一直很忙,它将无法提供更适合它的动态请求。

由于这些原因,Django静态视图仅设计用于开发期间,如果DEBUG设置为False,则它将不起作用。 .

因为在开发过程中,我们通常一次只有一个人访问站点

. exe), Django可以提供静态文件

当我创建DEBUG = True时,我的静态是不工作的。

如果我在python manage.py runserver --insecure中运行我的项目。这样我也得到了我的静电。

解决方案1:

python manage.py runserver --insecure

解决方案2:

但我需要永久的解决方案。然后我安装pip install dj-static==0.0.6,并添加一些代码到我的wsgi.py文件:

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


application = Cling(get_wsgi_application())

然后我在setting.py中添加了一些:

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

从这里我得到了一些帮助,混合了一些答案。这里,我把所有的部分相加。[我这样做是为了初学者的帮助,也是为了我将来的使用]

首先问题是为什么需要Debug=False ! 我把我的项目放在AWS中,由于内存泄漏,几个小时后连接超时。 一开始我想用芹菜。[当然我只是个初学者] 然后我将DEBUG=False from DEBUG=True As我们可以在settings.py

中看到安全警告
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
一旦我做到了,我的静态文件无法在网页上成功加载。 然后我到处搜索,首先尝试从这里——insecure命令运行服务器
python manage.py runserver --insecure

这是成功的,但我不希望我的项目在生产时处于不安全模式。 在我看来,正确的解决方法是以下步骤:

首先,我纠正了settings.py中的静态URL、根目录和目录

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

然后通过命令收集静态文件

python manage.py collectstatic

现在是第二步,[这里也提供了] 首先在你的项目目录的命令行

中安装whitenoise
pip install whitenoise

然后添加'whitenoise.middleware。在settings.py中中间件列表中的WhiteNoiseMiddleware'。

这应该添加在django.middleware.security下面。SecurityMiddleware'以及所有其他中间件。这样你的中间件列表看起来就像这样:-

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

在你安装的应用程序顶部添加'whitenoise.runserver_nostatic',这样你安装的应用程序列表将看起来像这样

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

完成后,您现在就可以在生产环境中提供静态文件了!![我对我当地的环境也是这样做的]

只要像往常一样使用runserver命令,不需要任何不安全或其他任何东西。

python manage.py runserver

< >强繁荣! !这对我很有用。 哈哈哈。我知道我有点孩子气,但我现在很开心

感谢所有在这里提供答案并帮助我工作的人。

我今天得到了这个问题,这在开发时解决了它,如果你仍然需要服务器本地静态(例如测试没有调试),你可以在不安全模式下运行devserver:

manage.py runserver --insecure

不要担心,因为在生产环境中,这个托管平台(Apache、Heroku et c)将为您处理静态文件的服务。

注意:Heroku不服务器静态文件,你会想把它放在AWS或MS Azure上