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

时间:2011-04-29 19:46:17

标签: django django-views django-staticfiles

正在使用Django构建应用程序作为我的主力。到目前为止一直都很好 - 指定数据库设置,配置静态目录,网址,视图等。但是,当我想要渲染我自己的漂亮和自定义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设置缺少的内容吗?

17 个答案:

答案 0 :(得分:414)

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

manage.py runserver --insecure

答案 1 :(得分:290)

关闭调试后,Django将不再为您处理静态文件 - 您的生产Web服务器(Apache或其他东西)应该处理这个问题。

答案 2 :(得分:25)

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

安装:

$.ajax({
    type : "POST",
    url : "GetConversation",
    response : "json",
    data : "rideID="+rideID,
    // if received a response from the server
    success : function(data, textStatus, jqXHR) {
        console.log("success");
        console.log(data.MessageInfo);
            $.each(data.MessageInfo, function(index, value) {
                console.log("Data Found");
                var eachrow = "<div class='conversation'>"
                    +"<div class='bubble'>"
                    +value.messageBody
                    +"<div class='pic'>" 
                    +"</div>"; 
                $('.messageContainer').prepend(eachrow);
            }); 
    },
    // If there was no resonse from the server
    error : function(jqXHR, textStatus, errorThrown) {
        // alert("Something really bad happened " + textStatus);
    }
});

wsgi.py 文件更改为:

pip install WhiteNoise

你很高兴去吧!

归功于Handlebar Creative Blog

但是,我们不建议在生产中以这种方式提供静态文件。您的生产Web服务器(如nginx)应该处理这个问题。

答案 3 :(得分:16)

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

  

警告

     

这只有在DEBUG为True时才有效。

     

那是因为这种观点非常严重   效率低,可能不安全。   这仅适用于本地   发展,永远不应该使用   在生产中。

Docs: serving static files in developent

编辑:您可以添加一些网址来测试您的404和500模板,只需在网址中使用通用视图direct_to_template。

from django.views.generic.simple import direct_to_template

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

答案 4 :(得分:11)

您实际上可以安全地在生产Django应用中提供静态文件,而不需要DEBUG=True

不要使用Django本身,而是在WSGI文件(dj_static)中使用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())

答案 5 :(得分:10)

约翰尼的answer很棒,但仅仅通过添加那里描述的那些线路,我仍然无法为我工作。基于这个答案,实际上对我有用的步骤:

  1. 按照说明安装WhiteNoise

    pip install WhiteNoise
    
  2. 创建STATIC_ROOT变量并将WhiteNoise添加到MIDDLEWARE中的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. 然后,按照Johnny的回答中的说明修改您的wsgi.py文件:

    #wsgi.py
    from django.core.wsgi import get_wsgi_application
    from whitenoise.django import DjangoWhiteNoise
    
    application = get_wsgi_application()
    application = DjangoWhiteNoise(application)
    
  4. 之后,将您的更改部署到您的服务器上(使用git或您使用的任何内容)。

  5. 最后,从服务器上的manage.py运行collectstatic选项。这会将静态文件夹中的所有文件复制到我们之前指定的STATIC_ROOT目录中:

    $ python manage.py collectstatic
    

    现在,您将看到一个名为staticfiles的新文件夹,其中包含此类元素。

  6. 完成以下步骤后,您现在可以运行服务器,并且可以在生产模式下查看静态文件。

    更新:如果你有版本&lt; 4 changelog表示不再需要在WSGI_APPLICATION = 'projectName.wsgi.application'文件中声明settings.py

答案 6 :(得分:7)

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

from django.views.static import serve 

在urlpatterns中添加这两个网址:

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

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

答案 7 :(得分:6)

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

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

您可以在True上更改settings.DEBUG,它将始终有效。但如果您的项目是严肃的,那么您应该考虑上面提到的其他解决方案。

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

答案 8 :(得分:4)

您可以通过多种方式对其进行调试。这是我的方法。

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

答案 9 :(得分:4)

这恰好是您必须在终端上键入才能在没有DEBUG = TRUE的情况下运行项目 然后您会看到所有资产(静态)文件都在本地服务器上正确加载。

python manage.py runserver --insecure 

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

答案 10 :(得分:2)

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

第1步:在settings.py中定义一个STATIC_ROOT路径

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

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

$ python manage.py collectstatic

第3步:现在定义URLConf,如果url的开头是static,则访问静态文件夹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, })
]

答案 11 :(得分:1)

最终解决方案:-
所以基本上当你使 debug = False 时,Django 不想处理你的静态文件。
所以我们想要一些可以照顾我们文件的东西。
答案是白噪声。

  1. pip install whitenoise 在您的环境中

  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',
        '...'
    ]
    

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

答案 12 :(得分:1)

nginx,settings 和 url 配置

如果您使用的是 linux,这可能会有所帮助。

nginx 文件

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

确保运行:

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

答案 13 :(得分:0)

这是正常和预期的行为。

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,则将无法使用。

由于在开发过程中,我们通常一次只有一个人访问该站点( developer),Django 可以提供静态文件。

答案 14 :(得分:0)

我对project / urls.py进行了以下更改,并且对我有用

添加此行: 从django.conf.urls导入URL

并添加:   url(r'^ media /(?P。*)$',服务,{'document_root':settings.MEDIA_ROOT,}), 在urlpatterns中。

答案 15 :(得分:0)

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

然后编辑如下:

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

那么如果settings.debug==False它不会对代码产生影响,那么在运行try python manage.py runserver --runserver以运行静态文件之后也是如此。

注意:信息仅应用于测试

答案 16 :(得分:0)

不推荐使用对url()的字符串视图参数的支持,并且将在Django 1.10中删除

我的解决方案只是上面Conrado解决方案的小修正。

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