【问题标题】:Adding expire header for Django static files on Heroku在 Heroku 上为 Django 静态文件添加过期标头
【发布时间】:2013-03-20 20:17:18
【问题描述】:

我正在尝试优化我的网页,但在我的静态文件上设置过期日期标题时遇到问题。

我正在运行 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 文件。

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

【问题讨论】:

    标签: django caching heroku


    【解决方案1】:

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

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

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

    【讨论】:

    • 至于“将您自己的视图组合在一起以提供文件并将自定义标头添加到 HttpResponse”,请参阅我的回答如何做到这一点。
    【解决方案2】:

    在生产中,您不应该使用 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')
    

    【讨论】:

      【解决方案3】:

      我认为,由于您将项目托管在 heroku 上,因此普遍接受的做法似乎是使用 S3 来提供静态文件。

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

      我对此不太确定,但我相信您应该能够在从 S3 提供文件时更改标头,至少这个 SO 问题似乎暗示了这种方式 Is it possible to change headers on an S3 object without downloading the entire object?

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-31
        • 2015-03-07
        • 2018-03-08
        • 2014-02-04
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        • 2015-05-11
        相关资源
        最近更新 更多