Tại sao DEBUG = Cài đặt sai làm cho truy cập tệp tĩnh django của tôi không thành công?


356

Đang xây dựng một ứng dụng sử dụng Django như công việc của tôi. Tất cả đều đã được cài đặt db, các thư mục tĩnh được định cấu hình, url, khung nhìn, v.v. Nhưng rắc rối bắt đầu lén lút trong khoảnh khắc tôi muốn hiển thị các trang 404.html và 500.html đẹp và tùy chỉnh của riêng mình.

Tôi đã đọc các tài liệu về xử lý lỗi tùy chỉnh và đặt các cấu hình cần thiết trong UrlsConf, tạo các chế độ xem tương ứng và thêm 404.html và 500.html vào thư mục mẫu của ứng dụng của tôi (cũng được chỉ định trong settings.txt).

Nhưng các tài liệu nói you can actually view custom error views until Debug is Off, vì vậy tôi đã tắt nó để kiểm tra công cụ của mình và đó là khi công cụ trở nên điên loạn!

Tôi không chỉ không xem 404.html tùy chỉnh (thực tế, nó tải, mà vì mỗi trang lỗi của tôi đều chứa thông báo lỗi đồ họa - như một số hình ảnh đẹp), nguồn của trang lỗi tải, nhưng không tải được gì nữa! Thậm chí không liên kết CSS hoặc Javascript!

Nói chung, một khi tôi đặt DEBUG = False, tất cả các chế độ xem sẽ tải, nhưng mọi nội dung được liên kết (CSS, Javascript, Hình ảnh, v.v.) sẽ không tải! Chuyện gì đang xảy ra vậy? Có thiếu thứ gì đó, liên quan đến các tệp tĩnh và DEBUGcài đặt không?


Làm thế nào bạn lưu trữ? Máy cục bộ với máy chủ thử nghiệm?
j_syk

máy cục bộ với máy chủ thử nghiệm. Về cơ bản tôi muốn xem cách xử lý lỗi tùy chỉnh của tôi sẽ hoạt động bằng cách mô phỏng các kịch bản cục bộ như truy cập các trang không tồn tại và gây ra lỗi thời gian chạy - nhưng nội dung tĩnh của tôi sẽ không tải.
nemeisfixx

Nó có thể được thực hiện ở cấp máy chủ như ở đây hoặc có thể được xử lý ở cấp Django bằng cách thêm urlpotype. Tôi tìm thấy câu hỏi dưới đây cho cùng một vấn đề. stackoverflow.com/questions/6405173/
Mạnh

Câu trả lời:


353

Khi gỡ lỗi, Django sẽ không xử lý các tệp tĩnh cho bạn nữa - máy chủ web sản xuất của bạn (Apache hoặc một cái gì đó) sẽ đảm nhiệm việc đó.


3
Điều này thực sự giải quyết sự tò mò của tôi, vì vậy bây giờ nó có ý nghĩa và tôi thực sự có thể chăm sóc nó với Apache nếu cần. Tôi nghĩ đó là một vấn đề với các thiết lập của riêng tôi. Cảm ơn
nemeisfixx

5
Tôi thấy câu trả lời này rất hữu ích. Chỉ trong trường hợp có người khác ở trong hoàn cảnh tương tự của tôi (sử dụng Google App Engine cho ứng dụng với django không liên quan): đừng quên cập nhật app.yaml.
Lyndsey Ferguson

3
trình xử lý: - url: / static static_dir: static
Lyndsey Ferguson

475

Nếu bạn vẫn cần máy chủ tĩnh cục bộ (ví dụ: để kiểm tra mà không gỡ lỗi), bạn có thể chạy devserver ở chế độ không an toàn:

manage.py runserver --insecure

6
Trong khi cờ này hoạt động, nó không phục vụ nội dung từ thư mục tập hợp
Howie

5
Đó là phép thuật. Cảm ơn ngài, bạn là một anh hùng. Câu trả lời này nên được hợp nhất với câu trả lời được chấp nhận vì nó giải quyết vấn đề mà không phải phục vụ tĩnh bằng cách khác so với django.
Depado

1
Đây là tất cả những gì tôi cần. Mặc dù cách thực hành tốt nhất là sử dụng biến môi trường để phân biệt giữa môi trường phát triển và sản xuất và chuyển đổi Debug.
Neeraj Gupta

1
Xin lưu ý: điều đó sẽ KHÔNG hoạt động với ManifestStaticFilesStorage dưới dạng code.djangoproject.com/ticket/19295
Andrea Rabbaglietti

9
ai đó có thể cho tôi biết mặc dù điều gì không an toàn về điều này
Kavi Vaidya

36

Bạn có thể sử dụng WhiteNaty để phục vụ các tệp tĩnh trong sản xuất.

Tải về:

pip install WhiteNoise

Và thay đổi tệp wsgi.py của bạn thành này:

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

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

Và bạn tốt để đi!

Tín dụng cho Blog sáng tạo tay cầm .

NHƯNG, nó thực sự không được khuyến khích phục vụ các tệp tĩnh theo cách này trong sản xuất. Máy chủ web sản xuất của bạn (như nginx) sẽ đảm nhận việc đó.


1
Nghe có vẻ thú vị, nhưng không hiệu quả với tôi khi chỉ thêm dòng đó vào wgsi.pytập tin. Tài liệu bạn liên kết dường như đưa ra các hướng dẫn khác để sử dụng WhiteNaty. Sẽ thử những cách khác và cập nhật cho bạn ở đây.
DarkCygnus

+1 vì đây là những gì cuối cùng đã dẫn tôi đến giải pháp. Tôi đã thêm một câu trả lời trong đó tôi bao gồm các bước bổ sung mà tôi đã thực hiện để làm cho nó hoạt động.
DarkCygnus

manage.py runserver --insecurekhông làm việc cho tôi. Điều này không, mặc dù.
Jee

3
Lưu ý rằng với bản phát hành WhiteNaty 4.0, cấu hình đã thay đổi. Không thêm các dòng này vào wsgi.py. Thay vào đó, chỉ cần thêm 'whitenoise.middleware.WhiteNoiseMiddleware'vào phần mềm trung gian. Xem ghi chú phát hành từ thay đổi
Doug Harris

Tại sao * không được đề xuất? Tôi đã sử dụng nó trong nhiều năm tại một số trang web, hoạt động rất tốt. Ngay cả Heroku cũng sử dụng nó trong mẫu Django của họ.
Omar Gonzalez

33

Trong urls.py tôi đã thêm dòng này:

from django.views.static import serve 

thêm hai url đó trong urlpotypes:

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

và cả tệp tĩnh và phương tiện đều có thể truy cập được khi DEBUG = FALSE.
Hy vọng nó giúp :)


Khi nó hoàn thành bảng quản trị css không tải ??
Doesitha Deepal

Đúng. Người duy nhất làm việc !! cảm ơn.
DrGeneral

TUYỆT VỜI! Đừng quên đặt STATIC_ROOT và Manage.txt collstatic.
DomingoR

2
Ngày nay thay thế url(bằngre_path(
Leopd

19

Nếu bạn đang sử dụng chế độ xem phục vụ tĩnh trong quá trình phát triển, bạn phải có DEBUG = True:

Cảnh báo

Điều này sẽ chỉ hoạt động nếu DEBUG là True.

Đó là bởi vì quan điểm này là không hiệu quả và có thể không an toàn. Điều này chỉ dành cho phát triển địa phương, và không bao giờ nên được sử dụng trong sản xuất.

Tài liệu: phục vụ các tệp tĩnh trong phát triển

EDIT: Bạn có thể thêm một số url chỉ để kiểm tra các mẫu 404 và 500 của mình, chỉ cần sử dụng chế độ xem chung direct_to_template trong các url của bạn.

from django.views.generic.simple import direct_to_template

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

1
Làm thế nào để một, sau đó phục vụ các tập tin tĩnh trên sản xuất? NVM, tôi chỉ thấy điều đó. Cảm ơn.

bạn sẽ thiết lập máy chủ web của mình để lưu trữ một thư mục cụ thể. Thông thường nhất bạn sẽ sử dụng Apache hoặc Nginx. Các tài liệu đi vào nó một chút.
j_syk

cảm ơn @j_syk, tôi đã thử cách tiếp cận này để xem 404.html và 500.html thông qua một số cơ chế không lỗi khác tương tự như những gì bạn đề xuất. Nhưng tôi muốn biết liệu hoàn toàn không thể có các trang của mình hiển thị chính xác như khi sản xuất hay không, trong khi vẫn chỉ chạy trên máy chủ thử nghiệm của tôi - ủy quyền xử lý tệp tĩnh cho Apache khi Debug tắt giải quyết cho tôi. Cảm ơn đã đóng góp.
nemeisfixx

@mcnemesis Tôi không chắc chắn chính xác điều gì sẽ xảy ra- nhưng hãy thử đặt TEMPLATE_DEBUG = Sai và DEBUG = True. Nếu bạn tắt các lỗi đẹp, tôi không chắc liệu nó có chuyển đến các mẫu 404/500 hay không
j_syk

như mong đợi, làm điều này không mang lại bất kỳ kết quả tích cực nào. Nhưng vẫn cảm ơn.
nemeisfixx

17

Câu trả lời của Johnny rất hay, nhưng vẫn không hiệu quả với tôi chỉ bằng cách thêm những dòng được mô tả ở đó. Dựa trên câu trả lời đó, các bước thực sự hiệu quả với tôi ở đâu:

  1. Cài đặt WhiteNaty như mô tả:

    pip install WhiteNoise
  2. Tạo STATIC_ROOTbiến và thêm WhiteNaty vào MIDDLEWAREbiến của bạn trong 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. Sau đó, sửa đổi wsgi.pytệp của bạn như được giải thích trong câu trả lời của Johnny:

    #wsgi.py
    from django.core.wsgi import get_wsgi_application
    from whitenoise.django import DjangoWhiteNoise
    
    application = get_wsgi_application()
    application = DjangoWhiteNoise(application)
  4. Sau đó, triển khai các thay đổi của bạn đến máy chủ của bạn (với git hoặc bất cứ điều gì bạn sử dụng).

  5. Cuối cùng, chạy collectstatictùy chọn từ manage.pymáy chủ của bạn. Điều này sẽ sao chép tất cả các tệp từ các thư mục tĩnh của bạn vào thư mục STATIC_ROOTchúng tôi đã chỉ định trước:

    $ python manage.py collectstatic

    Bây giờ bạn sẽ thấy một thư mục mới có tên staticfileschứa các yếu tố đó.

Sau khi làm theo các bước này, bây giờ bạn có thể chạy máy chủ của mình và sẽ có thể thấy các tệp tĩnh của bạn khi ở chế độ Sản xuất.

Cập nhật: Trong trường hợp bạn có phiên bản <4, thay đổi chỉ ra rằng không còn cần thiết phải khai báo WSGI_APPLICATION = 'projectName.wsgi.application'trên settings.pytệp của bạn .


Tôi đã làm nó theo đó, và khi phát triển nó đã phục vụ tốt, nhưng không phải trong sản xuất. Vẫn gặp vấn đề tương tự khi DEBUG == Sai
Anna Huang

@AnnaHuang Bạn có ý nghĩa gì trong quá trình phát triển và sản xuất? Bạn có môi trường hoặc máy móc riêng biệt? Chúng có được cấu hình theo cùng một cách không?
DarkCygnus

13

Bạn thực sự có thể phục vụ các tệp tĩnh trong ứng dụng Django sản xuất, an toàn và không có DEBUG=True.

Thay vì sử dụng Django, hãy sử dụng dj_static trong tệp WSGI của bạn ( 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())

2
Kể từ khi tôi phát hiện ra whitenoise , có thể đầy đủ tính năng hơn.
Robin Winslow

7

Chỉ cần mở urls.py dự án của bạn, sau đó tìm câu lệnh if này.

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

Bạn có thể thay đổi cài đặt.DEBUG trên True và nó sẽ hoạt động luôn. Nhưng nếu dự án của bạn là một cái gì đó nghiêm trọng thì bạn nên suy nghĩ về các giải pháp khác được đề cập ở trên.

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

Trong django 1.10 bạn có thể viết như vậy:

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

3
Mã của bạn là chính xác, nhưng trong Django 1.10, cấu hình dành cho phương tiện và tĩnh là: urlpotypes + = [url (r '^ media / (? P <path>. *) $', Phục vụ, {'document_root': settings .MEDIA_ROOT,}), url (r '^ static / (? P <path>. *) $', Phục vụ, {'document_root': settings.STATIC_ROOT}),]
Roberth Solís

6

Bạn có thể gỡ lỗi này theo nhiều cách khác nhau. Đây là cách tiếp cận của tôi.

localsinstall.py:

DEBUG = False
DEBUG404 = True

url:

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

Hãy chắc chắn để đọc các tài liệu;)

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


0

Hỗ trợ cho các đối số xem chuỗi thành url () không được dùng nữa và sẽ bị xóa trong Django 1.10

Giải pháp của tôi chỉ là điều chỉnh nhỏ cho giải pháp Conrado ở trên.

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

Mặc dù nó không an toàn nhất, nhưng bạn có thể thay đổi mã nguồn. hướng đếnPython/2.7/site-packages/django/conf/urls/static.py

Sau đó chỉnh sửa như sau:

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

Vì vậy, nếu settings.debug==Falsenó không ảnh hưởng đến mã, thì sau khi chạy hãy thử python manage.py runserver --runserverchạy các tệp tĩnh.

LƯU Ý : Thông tin chỉ nên được sử dụng để thử nghiệm


0

Tôi đã thực hiện các thay đổi sau cho dự án / urls.py của tôi và nó đã hoạt động với tôi

Thêm dòng này: từ url nhập django.conf.urls

và thêm: url (r '^ media / (? P. *) $', phục vụ, {'document_root': settings.MEDIA_ROOT,}), trong urlpotypes.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.