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

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

Когда я использовал содержимое моего procfile, как в руководстве ( 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.

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

Редактировать2

Я все еще не вижу свои статические файлы. Когда я нажимаю на изображение во время 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'),
)

person Bentley4    schedule 16.08.2012    source источник


Ответы (5)


Укажите свой STATIC_ROOT

Обычно я устанавливаю:

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

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

mkdir 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 уже говорит ему найти статические файлы в каталоге static каждого приложения с помощью этого: 'django.contrib.staticfiles.finders.AppDirectoriesFinder',

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

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

ДРУГОЕ РЕДАКТИРОВАНИЕ

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

Каждый 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. Сделать это довольно легко (и дешево).

person Francis Yaconiello    schedule 16.08.2012
comment
Я кое-что изменил после вашего ответа. Не могли бы вы проверить редактирование исходного сообщения? - person Bentley4; 17.08.2012
comment
проверьте это еще раз, я добавил некоторые пояснения. - person Francis Yaconiello; 17.08.2012
comment
как только вы изменили свой STATIC_ROOT, вы heroku run python manage.py collectstatic? не могли бы вы добавить вывод collectstatic? - person Francis Yaconiello; 17.08.2012
comment
не будет работать с героку, ср. эфемерная файловая система, а также только что ответил на другой вопрос @Bentley4 stackoverflow.com/a/12014658/343834 - person Maxime R.; 18.08.2012
comment
В прошлом я запускал collectstatic как часть запуска моего веб-воркера (в procfile), поэтому каждый раз, когда веб-воркер запускался или перезапускался, он собирал мои статические файлы, что приводило к тому, что меня не беспокоила эфемерная файловая система. Я бы порекомендовал S3 и приложение для хранения данных django (используйте S3 Boto), чтобы обойти это. - person Francis Yaconiello; 23.08.2012
comment
Перепробовав все, ничего не получалось, пока вы не подсказали мне перезапустить динамометр. Спасибо, теперь работает. - person Lawrr; 21.10.2015
comment
вау, это старо, хостинг сайтов django с heroku все еще является PIA? - person Francis Yaconiello; 22.10.2015

Есть одно решение.

В urls.py добавляем:

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/'

person AlexanderLedovsky    schedule 21.12.2012

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

person manojlds    schedule 18.03.2013

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

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

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

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

  2. Точно так же необходимо установить STATIC_URL (Django все равно выдаст ошибку ImproperlyConfigured, если вы этого не сделаете). Ваша текущая настройка '/static/' в порядке.

  3. В корневом каталоге 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!

person 3cheesewheel    schedule 07.10.2013

Я нашел здесь хороший способ решить все мои проблемы с Джанго на героку

person chuckis    schedule 23.01.2014