Почему установка 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) должен позаботиться об этом.

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

  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' на ваше 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 не хочет заботиться о ваших статических файлах.
Итак, нам нужно что-то, что может позаботиться о наших файлах.
Ответ - белошум.

  1. pip install whitenoise в вашей среде

  2. Добавьте 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',
        '...'
    ]
    
  3. Добавьте 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')} ),
    )

Обязательно прочитайте документы;)

https://docs.djangoproject.com/en/2.0/howto/static-files/

Это именно то, что вы должны ввести на терминале, чтобы запустить свой проект без 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:

  1. Добавлять 'whitenoise.middleware.WhiteNoiseMiddleware', в MIDDLEWARE
      MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware', # Add WhiteNoise here
    ...
]
  1. Добавлять 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'

  1. В вашей папке, содержащей 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>
Другие вопросы по тегам