Django sirve archivos estáticos con runserver pero no con capataz

I have the opposite problem to the one described in esta pregunta.

My Django site works correctly when the server is started using manage.py runserver but static files are not served when the server is started with foreman start.

Mi estructura de directorio:

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

Procfile (as described in the Primeros pasos con Django en Heroku tutorial):

web: gunicorn project.wsgi

configuración.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',
)

Like I said, all of this works correctly with runserveron my local machine, but not with foreman start.

Will post more info if requested.

preguntado el 23 de abril de 13 a las 14:04

2 Respuestas

The difference between runserver and foreman:

Django's runserver command serves static files because django.contrib.staticfiles automatically searches through your project's static folders for you (provided a few prerequisites are in place aquí) and returns them on static requests.

Foreman, however, is a separate utility from Django and knows nothing about Django's internals. So, you need some added help. Two good options are dj-static or Whitenoise. Either can be installed using pip. You will need to make a small modification to your wsgi.py file, as described in the setup instructions for whichever you choose (see links).

Both dj-static and whitenoise look in STATIC_ROOT in your settings.py file for static files. This is different than Django's runserver, which automatically traverses the various static folders in your project. This means you need to run manage.py collectstatic (which gathers your static files into STATIC_ROOT) before dj-static or whitenoise will find them.

Here is a set of example steps (for whitenoise):

Ejecutar:

pip install whitenoise

Modify wsgi.py to look like this:

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

application = DjangoWhiteNoise(get_wsgi_application())

Then static files will work:

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

Foreman requires a little more effort than runserver. However, foreman can closely mimic a production environment, whereas runserver will not (hopefully, it will not). Using dj-static or whitenoise in production is an okay choice in many situations. So, developing using foreman with dj-static or whitenoise will give you reassurance that major problems won't surprise you when your site moves to production. You don't get that reassurance from some other options (e.g. adding 'django.views.static.serve' to urls.py).

Respondido el 02 de enero de 15 a las 16:01

This is a bit of a hack but I got it working by adding this route to the urls:

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

Respondido 28 Abr '13, 11:04

This works and is awesome, but isn't there a cleaner way to do this? I don't remember having to hack settings.py like this with urls.py. Anyone have alternatives? - ApathyBear

This may be obvious to most, but as a python newb I stumbled for a bit before discovering that I need to add "import settings" at the top of the file as well. - MatrixManAtYrService

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.