为什么离开内置的runserver后Django找不到我的admin媒体文件?
当我使用内置的简单服务器时,一切都很好,管理员界面看起来很漂亮:
python manage.py runserver
但是,当我尝试用一个wsgi服务器和django.core.handlers.wsgi.WSGIHandler
来运行我的应用时,Django似乎忘记了管理员媒体文件的位置,导致管理员页面完全没有样式:
gunicorn_django
这是怎么回事呢?
3 个回答
我也遇到过这个问题(因为我在使用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>
。
Django 默认情况下不会提供媒体文件的服务,因为通常在另一个服务器上提供这些静态文件会更好(比如为了性能等原因)。所以,当你部署你的应用时,你需要确保设置一个其他的服务器(或者虚拟服务器)来提供媒体文件(包括管理界面的媒体文件)。你可以在 django/contrib/admin/media
找到管理界面的媒体文件。你应该设置你的 MEDIA_URL 和 ADMIN_MEDIA_URL,让它们指向这些媒体文件。更多信息可以查看 这个链接。
当我查看Django的源代码时,我发现了原因。
在django.core.management.commands.runserver
这个模块里,有一个WSGIHandler
对象被包裹在一个AdminMediaHandler
里面。
根据文档,AdminMediaHandler
是一个
WSGI中间件,它会拦截对管理员媒体目录的请求,这个目录是由
ADMIN_MEDIA_PREFIX
设置定义的,并提供这些图片。这个东西只能在本地使用,适合开发!它没有经过安全性测试,也不是特别高效。
所以,当我使用测试服务器时,管理员媒体文件只能自动找到。
现在我就手动设置管理员媒体的URL映射吧 :)