Проект Django с сервером gunicorn на Heroku не обслуживает статические файлы

Мой проект Django 1.3 обслуживает статические файлы на сервере разработки, но при этом не используются статические файлы сервера gunicorn. Я выполнил шаги этого руководства Heroku.

Когда я использовал содержимое моего профайла, как в руководстве ( web: gunicorn myproject_django.wsgi -b 0.0.0.0:$PORT) мой проект не был признан Heroku.

Затем я изменил этот файл Procfile:

web: python myproject_django/manage.py run_gunicorn -b 0.0.0.0:$PORT -w 3

Теперь мое приложение запускается, за исключением статических файлов (css неактивен и изображений).

Мое дерево проекта:

.
├── Procfile
├── myproject_django
│   ├── core
│   │   ├── admin.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── static
│   │   │   ├── css
│   │   │   │   ├── base.css
│   │   │   │   ├── layout.css
│   │   │   │   
│   │   │   └── media
│   │   │       ├── pek.ico
│   │   │       ├── pek.png
│   │   │       ├── pek_symbol.png
│   │   ├── tests.py
│   │   └── views.py
│   ├── __init__.py
│   ├── manage.py
│   ├── settings.py
│   ├── templates
│   │   └── core
│   │       ├── home.html
│   │       └── install.html
│   └── urls.py
└── requirements.txt

Потенциально соответствующие части settings.py

MEDIA_ROOT = ''

MEDIA_URL = '/static/media'

STATIC_ROOT = ''

STATIC_URL = '/static/'

ADMIN_MEDIA_PREFIX = '/static/admin/'

STATICFILES_DIRS = (
    os.path.abspath(__file__)+'/..'+'/myproject_django/core/static', 
)

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core',
    'gunicorn',
    'django.contrib.admin',
)

Изменить

Я скорректировал следующие вещи после вступления Фрэнсиса Якониэлло:

В settings.py

STATIC_ROOT = os.path.join(os.getcwd(),'core/static')
STATICFILES_DIRS = ( os.path.abspath(__file__)+'/..'+'/core/static', )

В gitignore:

staticfiles/*

Затем совершается. И, наконец, побежал heroku run python myproject_django/manage.py collectstatic.

Но статические файлы по-прежнему не обслуживаются, когда я просматриваю веб-страницу. Учитывая мое дерево каталогов, почему эти изменения не работали?

Edit2

Я все еще не вижу свои статические файлы. Когда я нажимаю на изображение, а DEBUG=True, я получаю следующее:

Request URL: http://myproject.herokuapp.com/static/media/pek.png

Дерево (обратите внимание: пул staticfiles пуст)

.
├── Procfile
├── myproject_django
│   ├── admin
│   ├── core
│   │   ├── admin.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── static
│   │   │   ├── css
│   │   │   │   ├── base.css
│   │   │   │   ├── layout.css
│   │   │   └── media
|   |   |       ├── pek.ico
|   │   │       ├── pek.png
|   │   │       ├── pek_symbol.png
│   │   ├── tests.py
│   │   ├── views.py
│   ├── __init__.py
│   ├── manage.py
│   ├── settings.py
│   ├── staticfiles
│   ├── templates
│   │   └── core
│   │       ├── 404.html
│   │       ├── 500.html
│   │       ├── home.html
│   │       └── install.html
│   ├── urls.py
└── requirements.txt

В settings.py

PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'static/media')
STATIC_ROOT = os.path.join(PROJECT_PATH,'staticfiles')
STATICFILES_DIRS = (
    os.path.join(PROJECT_PATH, 'core/static'),
)

Ответ 1

Укажите STATIC_ROOT

Я обычно устанавливаю его:

import os
STATIC_ROOT = os.path.join(os.getcwd(), "staticfiles")

создайте этот каталог в своем проекте

mkdir staticfiles

убедитесь, что содержимое staticfiles не отслеживается git

nano .gitignore

добавить

staticfiles/*

затем зафиксируйте его и нажмите на герою.

Наконец,

heroku run python manage.py collectstatic

ИЗМЕНИТЬ

STATIC_ROOT = os.path.join(os.getcwd(),'core/static')
STATICFILES_DIRS = ( os.path.abspath(__file__)+'/..'+'/core/static', )

Эти две настройки не могут быть одинаковыми.

STATICFILES_DIR В порядке, если ваш STATICFILES_FINDERS лишний раз говорит ему, что он находит staticfiles в каталоге static каждого приложения с помощью этого: 'django.contrib.staticfiles.finders.AppDirectoriesFinder',

Точка STATIC_ROOT заключается в предоставлении нового каталога, полностью отделенного от вашего проекта, который вы можете обслуживать на стороннем сервере, таком как nginx. Вот почему вы создали этот каталог staticfiles:

STATIC_ROOT = os.path.join(os.getcwd(),'staticfiles')

ДРУГИЕ ИЗОБРАЖЕНИЯ

обходной путь для эфемерной файловой системы

Каждый dyno получает свою собственную эфемерную файловую систему со свежей копией самого недавно развернутого кода. В течение жизненного цикла dynos его запущенные процессы могут использовать файловую систему в качестве временной блокнотной памяти, но никакие файлы, которые пишутся, не видны для процессов в любом другом dyno, и любые записанные файлы будут отброшены в момент остановки или перезапуска dyno.

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

web: python myproject_django/manage.py collectstatic --noinput; python myproject_django/manage.py run_gunicorn -b 0.0.0.0:$PORT -w 3

Тем не менее, я в настоящее время использую хранилища S3 и django http://django-storages.readthedocs.org/en/latest/index.html. Его довольно легко (и дешево), чтобы добиться этого.

Ответ 2

Существует одно решение.

В urls.py add:

from django.conf import settings

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

p.s. Для STATIC_URL = '/static/'

Ответ 3

Используйте run_collectstatic script, которые выполняются как часть post_compile, предоставленных heroku-django-cookbook. Он использует крюк post_compile, предоставленный пакетом python для Heroku

Ответ 4

Я столкнулся с той же проблемой; вам, кажется, нужны эти три настройки, в частности:

  • STATIC_ROOT должен быть определен в settings.py, например:

    STATIC_ROOT = os.path.join(PROJECT_PATH, 'served/static/')
    

    Где PROJECT_PATH - ваш корень проекта (в вашем случае - абсолютный путь к каталогу myproject_django.

  • Аналогично, также должен быть установлен STATIC_URL (Django в любом случае будет вызывать ошибку с неправильной конфигурацией, если вы этого не сделаете). Ваша текущая настройка '/static/' прекрасна.

  • В корневом каталоге urls.py настройте статические URL:

    from django.conf import settings
    from django.conf.urls.static import static  
    
    ...
    
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    

Наконец, запустите python manage.py collectstatic; это скопирует все файлы с /path/to/site-packages/django/contrib/admin/static/admin/ на /served/static/. (Вы можете узнать больше о том, как Django обслуживает статические файлы здесь).

Теперь, когда вы запустите foreman start, вы должны увидеть администратора с стилем.

Не забудьте добавить served/static/ к вашему .gitignore!

Ответ 5

Я нашел здесь хороший способ решить все мои проблемы с Django on heroku