为什么离开内置的runserver后Django找不到我的admin媒体文件?

3 投票
3 回答
1091 浏览
提问于 2025-04-15 23:54

当我使用内置的简单服务器时,一切都很好,管理员界面看起来很漂亮:

python manage.py runserver

但是,当我尝试用一个wsgi服务器和django.core.handlers.wsgi.WSGIHandler来运行我的应用时,Django似乎忘记了管理员媒体文件的位置,导致管理员页面完全没有样式:

gunicorn_django

这是怎么回事呢?

3 个回答

0

我也遇到过这个问题(因为我在使用gunicorn进行开发),下面是如何去掉admin-media的神奇设置,并通过urls.py像处理其他媒体文件一样来提供admin媒体的方法:

import os

import django

...

admin_media_url = settings.ADMIN_MEDIA_PREFIX.lstrip('/') + '(?P<path>.*)$'
admin_media_path = os.path.join(django.__path__[0], 'contrib', 'admin', 'media')

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^' + admin_media_url , 'django.views.static.serve', {
        'document_root': admin_media_path,
    }, name='admin-media'),
    ...
)

另外:http://djangosnippets.org/snippets/2547/

当然,还有 #include <production_disclaimer.h>

1

Django 默认情况下不会提供媒体文件的服务,因为通常在另一个服务器上提供这些静态文件会更好(比如为了性能等原因)。所以,当你部署你的应用时,你需要确保设置一个其他的服务器(或者虚拟服务器)来提供媒体文件(包括管理界面的媒体文件)。你可以在 django/contrib/admin/media 找到管理界面的媒体文件。你应该设置你的 MEDIA_URL 和 ADMIN_MEDIA_URL,让它们指向这些媒体文件。更多信息可以查看 这个链接

2

当我查看Django的源代码时,我发现了原因。

django.core.management.commands.runserver这个模块里,有一个WSGIHandler对象被包裹在一个AdminMediaHandler里面。

根据文档,AdminMediaHandler是一个

WSGI中间件,它会拦截对管理员媒体目录的请求,这个目录是由ADMIN_MEDIA_PREFIX设置定义的,并提供这些图片。这个东西只能在本地使用,适合开发!它没有经过安全性测试,也不是特别高效。

所以,当我使用测试服务器时,管理员媒体文件只能自动找到。

现在我就手动设置管理员媒体的URL映射吧 :)

撰写回答