DEBUG = False 설정으로 장고 정적 파일 액세스가 실패하는 이유는 무엇입니까?


356

Django를 내 주력으로 사용하여 앱을 만들고 있습니다. 지금까지 모두 DB 설정, 정적 디렉토리, 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 나 자바 스크립트도 연결되지 않았습니다!

일반적으로을 설정 DEBUG = False하면 모든보기가로드되지만 연결된 콘텐츠 (CSS, Javascript, Images 등)는로드되지 않습니다! 무슨 일이야? 정적 파일 및 DEBUG설정 과 관련하여 누락 된 것이 있습니까?


당신은 어떻게 호스팅하고 있습니까? 테스트 서버가있는 로컬 머신?
— j_syk

테스트 서버가있는 로컬 시스템. 기본적으로 존재하지 않는 페이지에 액세스하고 런타임 오류를 발생시키는 시나리오를 로컬로 시뮬레이션하여 사용자 지정 오류 처리가 어떻게 작동하는지 알고 싶지만 정적 콘텐츠가로드되지 않습니다.
— nemesisfixx

여기와 같은 서버 수준에서 수행하거나 urlpattern을 추가하여 장고 수준에서 처리 할 수 ​​있습니다. 나는 같은 문제에 대해 아래 질문을 찾았습니다. stackoverflow.com/questions/6405173/…
— Pankaj Anand

답변:


353

Django는 디버그가 꺼지면 더 이상 정적 파일을 처리하지 않습니다. 프로덕션 웹 서버 (Apache 또는 무언가)가 처리해야합니다.


3
이것은 실제로 내 호기심을 해결하므로 이제는 이해가되며 필요한 경우 Apache로 실제로 처리 할 수 ​​있습니다. 내 설정에 문제가 있다고 생각했습니다. 감사
— nemesisfixx

5
이 답변이 매우 유용하다는 것을 알았습니다. 다른 사람이 같은 상황에 처한 경우 (비상 대가있는 앱에 Google App Engine 사용) : app.yaml을 업데이트하는 것을 잊지 마십시오.
— Lyndsey Ferguson

3
핸들러 : - URL : / 정적의 static_dir : 정적
— 린지 퍼거슨

475

여전히 로컬에서 정적 서버를 사용해야하는 경우 (예 : 디버그없이 테스트하기 위해) 안전하지 않은 모드에서 devserver를 실행할 수 있습니다.

manage.py runserver --insecure

6
이 플래그가 작동하는 동안 collectstatic 폴더의 컨텐츠를 제공하지 않습니다
— Howie

5
마술이다. 감사합니다. 당신은 영웅입니다. 이 답변은 django 자체 이외의 다른 방법으로 정적 서비스를 제공하지 않고도 문제를 해결하므로 허용되는 답변과 병합되어야합니다.
— Depado

1
이것이 내가 필요한 전부였습니다. 가장 좋은 방법은 환경 변수를 사용하여 개발 및 프로덕션 환경과 디버그 토글을 구별하는 것입니다.
— Neeraj Gupta

1
제발 참고 : 그의 뜻으로 ManifestStaticFilesStorage하지 작업 code.djangoproject.com/ticket/19295
— 안드레아 Rabbaglietti

9
불안 때문에 이것에 대해 무엇을하지만 캔 누군가가 말해
— 카비 Vaidya

36

WhiteNoise 를 사용 하여 프로덕션에서 정적 파일을 제공 할 수 있습니다 .

설치:

pip install WhiteNoise

wsgi.py 파일을 다음 과 같이 변경하십시오 .

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

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

그리고 당신은 갈 수 있습니다!

핸들 바 크리에이티브 블로그에 크레딧 .

그러나 실제로 프로덕션에서 정적 파일을 제공하는 것은 권장하지 않습니다. 프로덕션 웹 서버 (예 : nginx)가이를 처리해야합니다.


1
흥미롭게 들리지만 wgsi.py파일에 해당 줄을 추가하여 나에게 효과가 없었습니다 . 연결 한 설명서에 WhiteNoise 사용에 대한 다른 지침이 나와 있습니다. 다른 방법으로 시도하고 여기에서 업데이트하십시오.
— DarkCygnus

이것이 결국 솔루션으로 이끌었던 +1입니다. 실제로 작동시키기 위해 수행 한 추가 단계를 포함 하는 답변을 추가 했습니다.
— DarkCygnus

manage.py runserver --insecure나를 위해 작동하지 않았다. 그러나 이것은 그렇습니다.
— Jee

3
WhiteNoise 릴리스 4.0에서는 구성이 변경되었습니다. 이 줄을 wsgi.py에 추가하지 마십시오. 대신 'whitenoise.middleware.WhiteNoiseMiddleware'미들웨어에 추가하십시오 .
— Doug Harris

* 권장하지 않는 이유는 무엇입니까? 여러 사이트에서 수년 동안 사용해 왔으며 훌륭하게 작동합니다. Heroku조차도 장고 템플릿에서 사용합니다.
— Omar Gonzalez

33

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 일 때 액세스 할 수있었습니다.
그것이 도움이되기를 바랍니다 :)


관리 패널 CSS 가로 드되지 않았습니까 ??
— Thusitha Deepal

예. 작동하는 유일한 사람 !! 감사.
— DrGeneral

대박! STATIC_ROOT 및 manage.py collectstatic을 설정하는 것을 잊지 마십시오.
— DomingoR

2
요즘 대체 url(:re_path(
— Leopd

19

개발시 정적 서브보기를 사용하는 경우 DEBUG = True가 있어야합니다.

경고

DEBUG가 True 인 경우에만 작동합니다.

이 견해는 매우 비효율적이며 아마도 안전하지 않기 때문입니다. 이것은 로컬 개발만을위한 것이며 프로덕션 환경에서 사용해서는 안됩니다.

문서 : 개발자의 정적 파일 제공

편집 : 404 및 500 템플릿을 테스트하기 위해 URL을 추가 할 수 있습니다 .URL에서 일반적인보기 direct_to_template을 사용하십시오.

from django.views.generic.simple import direct_to_template

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

1
프로덕션에서 정적 파일을 어떻게 제공합니까? NVM, 방금 봤어 감사.

특정 디렉토리를 호스팅하도록 웹 서버를 설정합니다. 가장 일반적으로 Apache 또는 Nginx를 사용합니다. 문서 는 약간 들어갑니다.
— j_syk

@j_syk 덕분에, 나는 이미 제안한 것과 비슷한 다른 오류가없는 메커니즘을 통해 404.html 및 500.html을 보는이 접근법을 이미 시도했습니다. 그러나 테스트 페이지에서 계속 실행하면서 프로덕션에서와 같이 페이지를 올바르게 렌더링하는 것이 완전히 불가능한지 알고 싶었습니다. 디버그가 꺼져있을 때 Apache에 정적 파일 처리를 위임하면 문제가 해결됩니다. 기여해 주셔서 감사합니다.
— nemesisfixx

@mcnemesis 정확히 어떻게 될지 잘 모르겠지만 TEMPLATE_DEBUG = False, DEBUG = True를 설정하십시오. 예쁜 오류를 끄면 404/500 템플릿으로 갈지 확실하지 않습니다
— j_syk

예상대로이 작업을 수행해도 긍정적 인 결과를 얻지 못했지만 여전히 감사합니다.
— nemesisfixx

17

Johnny의 대답 은 훌륭하지만 거기에 설명 된 줄을 추가해도 여전히 효과가 없었습니다. 그 대답을 바탕으로 실제로 나를 위해 일한 단계는 다음과 같습니다.

  1. 설명 된대로 WhiteNoise 를 설치하십시오 .

    pip install WhiteNoise
  2. 만들기 STATIC_ROOT변수를 당신에 백색 잡음을 추가 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. 그런 다음 wsgi.pyJohnny의 답변에 설명 된 대로 파일을 수정하십시오 .

    #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. 마지막으로 서버 collectstatic에서 옵션을 실행하십시오 manage.py. 그러면 정적 폴더의 모든 파일이 STATIC_ROOT이전에 지정한 디렉토리 로 복사됩니다 .

    $ python manage.py collectstatic

    이제 staticfiles이러한 요소가 포함 된 새 폴더가 나타납니다.

이 단계를 수행 한 후 이제 서버를 실행할 수 있으며 프로덕션 모드에서 정적 파일을 볼 수 있습니다.

업데이트 : 이 버전을 한 경우에는 <4 변경 로그 는 선언이 더 이상 필요하다고 나타냅니다 WSGI_APPLICATION = 'projectName.wsgi.application'당신에 settings.py파일.


나는 그에 따라 그것을했고, 개발에 대해서는 잘했지만 생산에는 없었습니다. DEBUG == False
— Anna Huang

@AnnaHuang 개발과 생산에서 무엇을 의미합니까? 별도의 환경이나 기계가 있습니까? 그들은 같은 방식으로 구성되어 있습니까?
— DarkCygnus

13

실제로 Django 앱에서 정적 파일을 안전하고 안전하게 제공 할 수 있습니다 DEBUG=True.

장고 자체를 사용하는 대신 WSGI 파일 ( github ) 에서 dj_static 을 사용 하십시오 .

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

2
나는 더 많은 기능을 갖춘 whitenoise를 발견 했다 .
— Robin Winslow

7

urls.py 프로젝트를 열고 if 문을 찾으십시오.

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

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

3
코드는 정확하지만 Django 1.10에서는 미디어에 대한 구성이며 정적은 다음과 같습니다. urlpatterns + = [url (r '^ media / (? P <path>. *) $', serve, { 'document_root': 설정 .MEDIA_ROOT,}), url (r '^ static / (? P <path>. *) $', 서브, { 'document_root': settings.STATIC_ROOT}),]
— Roberth Solís

6

여러 가지 방법으로 디버깅 할 수 있습니다. 여기 내 접근 방식이 있습니다.

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


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

0

가장 안전하지는 않지만 소스 코드에서 변경할 수 있습니다. 로 이동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정적 파일을 실행하십시오.

참고 : 정보는 테스트 목적으로 만 사용해야합니다


0

내 프로젝트 / urls.py를 다음과 같이 변경했는데 나에게 도움이되었습니다.

이 줄 추가 : from django.conf.urls import url

url (r '^ media / (? P. *) $'를 추가하고 urlpatterns에 { 'document_root': settings.MEDIA_ROOT,})를 게재하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.