【问题标题】:Media files are served, static files aren't提供媒体文件,不提供静态文件
【发布时间】:2012-06-15 18:47:07
【问题描述】:

由于an evergreen issue,我被卡住了,没有提供静态文件。相反,放在MEDIA_ROOT 子树中的文件会在MEDIA_URL 下正确提供。

剥离settings.py:

DEBUG = True
STATIC_URL = '/static/'
STATIC_ROOT = '/home/foo/devel/static'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/foo/devel/media'
# the following is deprecated but is it seems grappelly requires it
ADMIN_MEDIA_PREFIX = STATIC_URL + "grappelli/"
STATIC_FILES = ()
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

创建我所做的项目:

$ cd /home/foo/devel/
$ virtualenv testdrive
$ . bin/activate; pip install django; cd testdrive
$ django-admin.py fbtest

并得到这个目录树(剥离):

. <-- /home/foo/devel/
├── bin
├── fbtest
│   └── fbtest
│       ├── media
│       │   └── foo.jpg
│       ├── static
│       └────── foo.jpg
├── include
└── lib

STATIC_URL 下的文件应该由 Django 静态文件自动提供(在我的情况下不是),而其他文件必须手动处理。所以我将这些行附加到urls.py:

import settings
if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip("/"),
            'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),
    )

访问http://host/media/filebrowser/foo.jpg 有效,而http://host/static/foo.jpg 给出错误404。为什么?

【问题讨论】:

  • 你用的是什么版本的django?
  • 你能把INSTALLED_APPS添加到剥离的settings.py文件中吗?
  • 你能解释一下这里的“常青树”是什么意思吗?谷歌没用。
  • @JordanReiter 感谢您的指点,问题确实存在。 See my answer.
  • 对不起。我的意思是一个经常讨论的经典问题。

标签: django static-files django-staticfiles


【解决方案1】:

这是一个愚蠢的错误。我忘记将fbtest 添加到INSTALLED_APPS,所以静态文件机制没有管理这个应用程序的静态文件。

【讨论】:

    【解决方案2】:

    STATIC_URL 下的文件应由 Django 静态文件自动提供(在我的情况下不是),而其他文件必须手动处理。

    这是不正确的。 Django 从来没有为STATIC_ROOT 服务过——甚至在开发中也没有。它所做 所做的是使每个应用程序的“静态”目录中的文件和STATICFILES_DIRS 中指定的任何目录中的文件在STATIC_URL 中可用。您实际上并没有手动在STATIC_ROOT 中放入任何东西;事实上,在开发中,您甚至不应该在那里拥有目录。简而言之,当您运行 collectstatic 管理命令时,STATIC_ROOT 只是您生产中静态文件的垃圾场。

    在开发中,所有静态文件都应该进入someapp/static,其中“someapp”是它们应用的应用程序。如果文件作为一个整体应用于项目,例如全局 CSS 文件,则需要创建一个完全不同的目录(即 STATIC_ROOTMEDIA_ROOT 相同)然后将该目录添加到STATICFILES_DIRS。例如,我通常称我的“资产”,所以:

    STATICFILES_DIRS = (
        os.path.join(os.path.dirname(__file__), 'assets'),
    )
    

    【讨论】:

    • +1 感谢您的精彩解释,现在事情更清楚了。
    • @Chris Pratt:您如何引用someapp/static 中的应用程序?对我来说,STATIC_URL 只能访问STATIC_ROOT (Django 1.3) 中可用的文件。
    • @Mr.Dave:这是在开发还是在生产中。在开发中,完全删除STATIC_ROOT 目录。我注意到 Django 倾向于在开发中从那里提供文件如果它存在,而不是实际引用所有应用程序的静态目录和 STATICFILES_DIRS 中的任何内容。在生产中,只需运行 collectstatic 将所有内容复制到那里,然后使用您的 Web 服务器提供该目录。
    • @ChrisPratt:谢谢,我认为这是导致问题的原因!
    【解决方案3】:

    这个问题真的是常青树... 一些提示:

    TEMPLATE_CONTEXT_PROCESSORS = (
        # ...
        'django.core.context_processors.static',
        # ...
    )
    
    INSTALLED_APPS = (
        # ...
        'django.contrib.staticfiles',
        # ... 
    )
    

    我对 django 1.4 的设置(没有 grappelli):

    urls.py

    if settings.DEBUG:
        urlpatterns = patterns('',
    
            url(r'^%s(?P<path>.*)$' % settings.STATIC_URL.lstrip('/'), 'django.views.static.serve',
                {'document_root': settings.STATIC_ROOT, "show_indexes": True}),
    
            url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip('/'), 'django.views.static.serve',
                {'document_root': settings.MEDIA_ROOT, "show_indexes": True}),
    
        ) + urlpatterns
    

    settings.py

    MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media')
    STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
    MEDIA_URL = '/media/'
    STATIC_URL = '/static/'
    ADMIN_MEDIA_PREFIX = '/static/admin/'
    
    
    TEMPLATE_CONTEXT_PROCESSORS = (
        # ...
        'django.core.context_processors.static',
        # ...
    )
    
    INSTALLED_APPS = (
        # ...
        # 'django.contrib.staticfiles',
        # ...
    )
    

    【讨论】:

    • 谢谢。 1. 我试过但没有帮助。 2. 既不将show_indexes: True 添加到字典中。 3. 是的,virtualenv 创建一个包含以下链接的local 目录:bin -&gt; /home/foo/devel/testdrive/bininclude -&gt; /home/foo/devel/testdrive/includelib -&gt; /home/foo/devel/testdrive/lib4. 抱歉,我不知道如何使用 --adminmedia 选项。
    • python manage.py runserver --adminmedia=../path-to-grappelli/grappelli/static/grappelli
    • adminmedia 是基本的 djago 命令...=>docs
    • 尝试设置 MEDIA_ROOT = '/home/foo/devel/fbtest/fbtest/media'
    • 将 MEDIA_ROOT 设置为该值并不能解决 /static/ 问题,并会破坏以前有效的 /media/ 服务。让我调查一下缺少的 --adminmedia 选项...
    猜你喜欢
    • 2017-10-28
    • 1970-01-01
    • 2017-10-15
    • 2012-10-29
    • 2012-07-07
    • 2020-05-21
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    相关资源
    最近更新 更多