Почему установка DEBUG = False приводит к сбою доступа к моим статическим файлам в django?

295

Я создаю приложение, использующее 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 (фактически, он загружается, но поскольку на моих страницах ошибок есть графическое сообщение об ошибке -as, какое-то приятное изображение), источник страницы ошибки загружается, но ничего больше не загружается! Даже не связаны CSS или Javascript!

Как правило, когда я устанавливаю DEBUG = False, все представления загружаются, но любой связанный контент (CSS, Javascript, изображения и т.д.) Не загружается! Что происходит? Что-то не хватает, что касается статических файлов и настроек DEBUG?

  • 0
    Как вы хостинг? Локальная машина с тестовым сервером?
  • 0
    локальная машина с тестовым сервером. Я в основном хочу посмотреть, как моя пользовательская обработка ошибок будет работать, локально моделируя сценарии, такие как доступ к несуществующим страницам и вызывая ошибки во время выполнения - но мой статический контент не загружается.
Показать ещё 1 комментарий
Теги:
django-views
django-staticfiles

12 ответов

263
Лучший ответ

С отключением отладки Django больше не будет обрабатывать статические файлы - ваш рабочий веб-сервер (Apache или что-то еще) должен позаботиться об этом.

  • 1
    Это фактически решает мое любопытство, так что теперь это имеет смысл, и я действительно могу позаботиться об этом с Apache, если это будет необходимо. Я думал, что это была проблема с моими собственными настройками. Спасибо
  • 4
    Я нашел этот ответ очень полезным. На всякий случай, если кто-то еще находится в моей ситуации (используя Google App Engine для приложения с nonrel django): не забудьте обновить app.yaml.
Показать ещё 2 комментария
403

Если вам все еще нужно локально статически на сервере (например, для тестирования без отладки), вы можете запустить devserver в небезопасном режиме:

manage.py runserver --insecure
  • 0
    Я получаю ./manage.py: error: no such option: --insecure
  • 0
    @astrocybernaute убедитесь, что у вас установлено приложение staticfiles
Показать ещё 13 комментариев
23

Вы можете использовать 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)

И ты в порядке!

Кредит для творческого блога Handlebar.

НО, это действительно не рекомендуется использовать статические файлы таким образом в производстве. Ваш производственный веб-сервер (например, nginx) должен позаботиться об этом.

  • 1
    Звучит интересно, но у меня не получилось, просто добавив эту строку в файл wgsi.py Документация, на которую вы ссылаетесь, похоже, содержит другие инструкции по использованию WhiteNoise. Попробую другие способы и обновлю вас здесь.
  • 0
    +1, как это было то, что в конечном итоге привело меня к решению. Я добавил ответ, где я включил дополнительные шаги, которые я предпринял, чтобы фактически заставить его работать.
Показать ещё 1 комментарий
16

Если вы используете статическое представление службы в разработке, вы должны иметь DEBUG = True:

Предупреждение

Это будет работать, только если DEBUG имеет значение True.

Это потому, что это мнение грубо неэффективен и, вероятно, небезопасен. Это предназначено только для локальных разработки и никогда не должны использоваться в производстве.

Документы: обслуживание статических файлов в разработке

EDIT: вы можете добавить некоторые URL-адреса, чтобы протестировать ваши 404 и 500 шаблонов, просто используйте общий вид direct_to_template в своих URL-адресах.

from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
    ('^404testing/$', direct_to_template, {'template': '404.html'})
)
  • 1
    Как один, а затем обслуживать статические файлы на производстве? NVM, я только что видел это. Благодарю.
  • 0
    Вы должны настроить свой веб-сервер для размещения определенного каталога. Чаще всего вы используете Apache или Nginx. Документы идут в это немного.
Показать ещё 3 комментария
11

Фактически вы можете обслуживать статические файлы в рабочем приложении Django, безопасно и без DEBUG=True.

Вместо использования самого Django используйте dj_static в файле WSGI (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
    С тех пор я обнаружил белый шум , который может быть более полнофункциональным.
10

Ответ Джонни великолепен, но у меня все равно не получилось, просто добавив те строки, которые там описаны. Исходя из этого ответа, шаги, которые на самом деле помогли мне, где:

  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. Затем измените файл 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. Наконец, запустите опцию collectstatic из вашего manage.py на вашем сервере. Это скопирует все файлы из ваших статических папок в каталог STATIC_ROOT мы указали ранее:

    $ python manage.py collectstatic
    

    Теперь вы увидите новую папку с именем staticfiles которая содержит такие элементы.

После выполнения этих шагов вы можете запустить свой сервер и сможете видеть ваши статические файлы, находясь в производственном режиме.

Обновление: если у вас версия <4, WSGI_APPLICATION = 'projectName.wsgi.application' изменений показывает, что больше не нужно объявлять WSGI_APPLICATION = 'projectName.wsgi.application' в вашем файле settings.py.

7

В urls.py я добавил эту строку:

from django.views.static import serve 

добавьте эти два URL-адреса в 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.
Надеюсь, поможет :)

  • 2
    На сегодняшний день это единственное, что сработало! +1
6

Просто откройте свой проект 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 }), ]
  • 3
    Ваш код верен, но в Django 1.10 конфигурация для носителей и статических: urlpatterns + = [url (r '^ media / (? P <путь>. *) $', Serve, {'document_root': settings .MEDIA_ROOT,}), url (r '^ static / (? P <путь>. *) $', Serve, {'document_root': settings.STATIC_ROOT}),]
  • 0
    Да ты прав.
Показать ещё 1 комментарий
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

0

Я внес следующие изменения в свой проект /urls.py, и он работал на меня

Добавьте эту строку из URL импорта django.conf.urls

и добавьте url (r '^ media/(? P. *) $', serve, {'document_root': settings.MEDIA_ROOT,}) в urlpatterns.

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 для запуска статических файлов.

ПРИМЕЧАНИЕ. Информация должна использоваться только для тестирования

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню