在Heroku上为Django静态文件添加expire头

时间:2013-03-30 04:24:20

标签: django caching heroku

我正在尝试优化我的网页,并且无法在我的静态文件上设置过期日期标题。

我正在运行django-1.5,python-2.7.3。

这是我在settings.pyso中的缓存设置:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': os.path.join(PROJECT_ROOT, 'cache/'),
    }
}

CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 5 * 60
CACHE_MIDDLEWARE_KEY_PREFIX = ''

MIDDLEWARE_CLASSES = (
    'django.middleware.cache.UpdateCacheMiddleware',
    ...
    'django.middleware.cache.FetchFromCacheMiddleware',
)

我在settings.py中的静态文件设置:

import os.path

PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(PROJECT_DIR, '..'))

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles/')

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(PROJECT_DIR, 'static'),
)

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

我发现最接近的建议是here,但我无法修改Heroku上的.htaccess文件。

非常感谢任何帮助。谢谢!

3 个答案:

答案 0 :(得分:5)

django staticfiles应用程序不提供对自定义标头的开箱即用支持。您必须将您自己的视图组合在一起以提供文件并将自定义标头添加到HttpResponse。

但是你不应该使用Django提供静态文件。 这是一个糟糕的主意

  1. Django是单线程的,并且阻塞。因此,每当您为用户提供静态文件时,您实际上并没有提供任何其他服务(包括您的应用程序代码,这就是Django的用途)。
  2. Django的静态视图文件不安全,不稳定。该文档明确表示不在生产中使用它。所以不要在生产中使用它。如初。

答案 1 :(得分:1)

在制作中,你不应该使用Django提供静态文件。请参阅此页面上的警告框:https://docs.djangoproject.com/en/1.4/ref/contrib/staticfiles/#static-file-development-view

在开发过程中,Django的contrib.staticfiles应用程序会通过覆盖runserver命令自动为您提供静态文件。这样您就无法控制它为静态文件提供服务的方式。

您可以通过向runserver命令添加--nostatic选项来阻止staticfiles应用程序提供静态文件:

./manage.py runserver --nostatic

然后你可以编写一个url配置来手动提供你想要的标题的静态文件:

from functools import wraps
from django.conf import settings
from django.contrib.staticfiles.views import serve as serve_static
from django.conf.urls import patterns, url

urlpatterns = patterns('', )

if settings.DEBUG:

    def custom_headers(view_func):

        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            response = view_func(request, *args, **kwargs)
            response['Custom-header'] = 'Awesome'
            response['Another-header'] = 'Bad ass'
            return response

        return wrapper

    urlpatterns += patterns('',
        url(r'^static/(?P<path>.*)$', custom_headers(serve_static)),
    )

如果您希望manage.py默认启用--nostatic选项,则可以将其添加到manage.py

if '--nostatic' not in sys.argv:
    sys.argv.append('--nostatic')

答案 2 :(得分:0)

我认为既然您在heroku上托管您的项目,那么普遍接受的做法似乎是使用S3来提供静态文件。

看看这个问题: Proper way to handle static files and templates for Django on Heroku

我对此并不太确定,但我确信你应该能够在从S3提供文件时更改标题至少这个问题似乎建议这样 Is it possible to change headers on an S3 object without downloading the entire object?

希望这有帮助