Почему установка 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
установка?
23 ответа
С отключенной отладкой Django больше не будет обрабатывать статические файлы - ваш рабочий веб-сервер (Apache или что-то еще) должен позаботиться об этом.
Если вам все еще нужно локально статически настроить сервер (например, для тестирования без отладки), вы можете запустить devserver в небезопасном режиме:
manage.py runserver --insecure
В 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.
Надеюсь, поможет:)
Вы можете использовать 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) должен позаботиться об этом.
Ответ Джонни великолепен, но он все равно не сработал для меня, просто добавив строки, описанные там. Исходя из этого ответа, шаги, которые на самом деле работали для меня, где:
Установите WhiteNoise, как описано:
pip install WhiteNoise
Создать
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
Затем измените ваш
wsgi.py
файл, как объяснено в ответе Джонни:#wsgi.py from django.core.wsgi import get_wsgi_application from whitenoise.django import DjangoWhiteNoise application = get_wsgi_application() application = DjangoWhiteNoise(application)
После этого разверните свои изменения на своем сервере (с помощью git или чего-либо еще).
Наконец, запустите
collectstatic
вариант из вашегоmanage.py
на вашем сервере. Это скопирует все файлы из ваших статических папок вSTATIC_ROOT
каталог, который мы указали ранее:$ python manage.py collectstatic
Теперь вы увидите новую папку с именем
staticfiles
который содержит такие элементы.
Выполнив следующие действия, вы теперь можете запустить свой сервер и сможете видеть ваши статические файлы в рабочем режиме.
Обновление: если у вас была версия < 4, журнал изменений указывает, что больше не нужно объявлять WSGI_APPLICATION = 'projectName.wsgi.application'
на ваше settings.py
файл.
Если вы используете статическое представление подачи в разработке, вы должны иметь DEBUG = True:
Предупреждение
Это будет работать, только если DEBUG - True.
Это потому, что эта точка зрения крайне неэффективна и, вероятно, небезопасна. Это предназначено только для местного развития и никогда не должно использоваться в производстве.
Документы: обслуживание статических файлов в разработке
РЕДАКТИРОВАТЬ: Вы можете добавить некоторые 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'})
)
На самом деле вы можете обслуживать статические файлы в рабочем приложении 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())
Отсюда я получил помощь, смешав несколько ответов. Здесь я добавляю целые части. [Я делаю это для помощи новичкам, а также для моего будущего использования]
Ну сначала вопрос почему
Debug=False
нужный! Я поместил свой проект в AWS, и через несколько часов истекло время ожидания соединения из-за утечки памяти. Сначала я подумал о сельдерее. [конечно, я всего лишь новичок] Тогда я поставил
DEBUG=False
из
DEBUG=True
Как мы видим предупреждение безопасности в settings.py
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
Однажды я сделал это, мои статические файлы не загружались успешно на веб-страницах. Затем я искал везде и сначала попробовал отсюда команду --insecure для запуска сервера.
python manage.py runserver --insecure
Это успешно, но мне не нужен небезопасный режим в моем проекте, когда он находится в производстве. И в качестве правильного решения [по моему мнению] я выполнил следующие шаги.
Сначала я исправляю статический URL, корень и каталог в settings.py .
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.WhiteNoiseMiddleware» в список промежуточного программного обеспечения в settings.py.
Это должно быть добавлено чуть ниже «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
Бум!!! Это работает для меня. Хахаха. Я знаю своего рода детскую натуру, но сейчас я так счастлива.
Спасибо всем, кто дал ответы здесь и помогает моей работе.
Окончательное решение:-
Итак, когда вы делаете debug = False, Django не хочет заботиться о ваших статических файлах.
Итак, нам нужно что-то, что может позаботиться о наших файлах.
Ответ - белошум.
pip install whitenoise в вашей среде
Добавьте whitenoise.middleware.WhiteNoiseMiddleware в свой список промежуточного программного обеспечения в settings.py.
Его следует добавить чуть ниже django.middleware.security.SecurityMiddleware и выше всего оставшегося промежуточного программного обеспечения. Итак, ваш список промежуточного программного обеспечения будет выглядеть так: -
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', # add it exactlyhere 'django.contrib.sessions.middleware.SessionMiddleware', '...' ]
Добавьте whitenoise.runserver_nostatic поверх установленных приложений, чтобы список установленных приложений выглядел так: -
INSTALLED_APPS = [ 'whitenoise.runserver_nostatic', 'django.contrib.admin', 'django.contrib.auth', '...' ]
Готово, теперь вы можете обслуживать статические файлы в продакшене !!
Просто откройте свой проект 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 }), ]
Вы можете отладить это разными способами. Вот мой подход.
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')} ),
)
Обязательно прочитайте документы;)
Это именно то, что вы должны ввести на терминале, чтобы запустить свой проект без DEBUG = TRUE, и тогда вы увидите, что все файлы ресурсов (статические) загружаются правильно на локальном сервере.
python manage.py runserver --insecure
--insecure
: это означает, что вы можете запустить сервер без режима безопасности
когда я делаю
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",
]
Я согласен с ответом Марека Сапкоты; Но вы все равно можете использовать django URFConf для перераспределения URL- адреса, если запрашивается статический файл.
Шаг 1. Определите STATIC_ROOT
путь в settings.py
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, })
]
Я столкнулся с этой проблемой сегодня, и это исправило ее во время разработки. Если вам все еще нужен статический сервер локально (например, для тестирования без отладки), вы можете запустить devserver в небезопасном режиме:
manage.py runserver --insecure
Не беспокойтесь, потому что во время работы эта хостинговая платформа (Apache, Heroku и т. д.) будет обрабатывать статические файлы для вас.
Примечание. Heroku не серверирует статические файлы, вы хотите разместить его на AWS или MS Azure.
nginx, настройки и конфиги URL
Если вы используете Linux, это может помочь.
nginx файл
your_machn: / #vim и т. д. / 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/'
if DEBUG:
STATIC_ROOT = '/var/www/your_prj/static/'
MEDIA_ROOT = '/var/www/your_prj/media/'
else:
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
Это нормальное и предполагаемое поведение.
Warning
This will only work if DEBUG is True.
you can actually view custom error views until Debug is Off
Если Django просто читает из файловой системы и отправляет файл, то у него нет преимуществ перед обычным веб-сервером, все веб-серверы способны самостоятельно обрабатывать файлы.
Более того, если вы обслуживаете статические файлы с помощью Django, вы будете держать процесс Python занятым на время запроса, и он не сможет обслуживать динамические запросы, для которых он больше подходит.
По этим причинам статическое представление Django предназначено только для использования во время разработки и не будет работать, если для параметра DEBUG установлено значение False.
Поскольку во время разработки у нас обычно есть доступ к сайту только одному человеку (разработчику), Django может обслуживать статические файлы.
Поддержка аргументов строкового представления для 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')} ),
)
В производственном режиме статические файлы больше не обслуживаются Django, а должны обслуживаться Apache или NGINX, и, следовательно, вам необходимо будет их настроить.
С другой стороны, если вы хотите, чтобы Django обслуживал их, то приведенный ниже код позволяет позволить Django обслуживать статические файлы, когдаDEBUG=False
.
Вы можете попробовать это, добавив приведенный ниже код в основнойurls.py
файл:
from django.urls import re_path
from django.views.static import serve
urlpatterns += (
re_path(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),
re_path(r'^static/(?P<path>.*)$', serve,{'document_root': settings.STATIC_ROOT}),
)
Затем выполните «collectstatic»:
python manage.py collectstatic
Спасибо @stathoula. После ее ответа вместе с замечанием user303056 (добавивre_path
ее ответ).
Я внес следующие изменения в свой проект /urls.py, и он работал на меня
Добавьте эту строку: из URL импорта django.conf.urls
и добавьте: url(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT, }) в urlpatterns.
Хотя это не самый безопасный, но вы можете изменить в исходном коде. перейдите к 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
запускать статические файлы.
ПРИМЕЧАНИЕ: информация должна использоваться только для тестирования
Установить
pip install whitenoise
(текущая версия - 5.2.0)
В твоей
settings.py
:
- Добавлять
'whitenoise.middleware.WhiteNoiseMiddleware',
вMIDDLEWARE
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Add WhiteNoise here
...
]
- Добавлять
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
ревет твойSTATIC_ROOT
if DEBUG:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
...
else:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
- В вашей папке, содержащей
manage.py
запуститьpython manage.py collectstatic
(Для статического файла сайта администратора Django)
Это работает для меня:
if DEBUG:
<p>STATIC_ROOT = os.path.join(BASE_DIR, "static")</p>
<p>STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'</p>
<p>else:</p>
<p>STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")</p>