Django使用runserver提供静态文件,但不提供foreman

时间:2013-04-23 13:00:22

标签: django heroku foreman

我遇到与this question中描述的问题相反的问题。

当使用manage.py runserver启动服务器时,我的Django站点正常工作,但当服务器以foreman start启动时,不会提供静态文件。

我的目录结构:

project_name/
  project/
    settings.py
    ...
  app/
    ...
  venv/
    ...
  public/
    static/
      # static files go here #
    media/
      ...
  Procfile
  requirements.txt
  manage.py

Procfile(如Getting Started with Django on Heroku教程中所述):

web: gunicorn project.wsgi

settings.py:

import os
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
UP_ROOT = os.path.abspath(os.path.join(SITE_ROOT, '..'))
...
MEDIA_ROOT = UP_ROOT + '/public/media/'
...
STATIC_ROOT = UP_ROOT + '/public/static'
...
STATIC_URL = '/static/'
...
STATICFILES_DIRS = (
UP_ROOT + '/public',
UP_ROOT + '/public/static',
)

就像我说的,所有这一切都适用于我本地计算机上的runserver,但不适用于foreman start

如果要求,会发布更多信息。

2 个答案:

答案 0 :(得分:7)

runserver和foreman之间的区别:

Django的runserver命令提供静态文件,因为django.contrib.staticfiles会自动搜索项目的静态文件夹(前提是有一些先决条件here)并返回它们静态请求。

然而,Foreman是一个与Django不同的实用程序,对Django的内部结构一无所知。所以,你需要一些额外的帮助。两个不错的选择是dj-staticwhitenoise。可以使用pip安装。您需要对wsgi.py文件进行一些小修改,如您选择的设置说明中所述(参见链接)。

dj-static和whitenoise在您的settings.py文件中查看静态文件的STATIC_ROOT。这与Django的runserver不同,后者自动遍历项目中的各种静态文件夹。这意味着您需要在dj-static或whitenoise找到它们之前运行manage.py collectstatic(将静态文件收集到STATIC_ROOT中)。

以下是一组示例步骤(针对whitenoise):

执行命令

pip install whitenoise

将wsgi.py修改为如下所示:

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = DjangoWhiteNoise(get_wsgi_application())

然后静态文件将起作用:

# Run collectstatic before foreman whenever you've changed static files
python manage.py collectstatic
foreman start

Foreman需要比runserver更多的努力。但是,工头可以非常模仿生产环境,而runserver则不会(希望,它不会)。在许多情况下,在生产中使用dj-static或whitenoise是一个不错的选择。因此,使用带有dj-static或whitenoise的工头进行开发将让您放心,当您的网站投入生产时,主要问题不会给您带来惊喜。你不能从其他一些选项中得到这种保证(例如,将django.views.static.serve'添加到urls.py)。

答案 1 :(得分:4)

这有点像黑客,但我通过将这条路线添加到网址来实现它:

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