`
limodou
  • 浏览: 64727 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

[Django]APP级别的静态文件处理

阅读更多

静态文件在 django 中并不是非常简单的事情。由于URL与文件目录并不是相同的东西,因此在处理 Django 中的静态文件时要同时考虑两个东西,一个就是静态文件的URL表示,另一个就是如果将静态文件的URL与实际的文件路径相对应起来。而在 Django 中标准的处理静态文件的方式是通过webserver,通过ReWrite规则,将一个URL的表示映射为实际的目录。因此这种做法要求我们将静态文件集中管理,比如都放在某个media目录下,分为css, js, images等子目录,并且将整个项目所用到的所有静态文件都分别放在这个目录下。这样做的好处主要是为了方便映射。但同时造成一个问题:一个APP它应该是相对自包含的,如有自已的Model,有自已的templates目录,有自已的templatetags目录。但唯独到了静态文件这块,由于这种集中管理的要求无法分散到各自的目录下,使得管理起来变得麻烦和复杂。

那么为什么会这样?我思考了一段时间。有一个叫ToscaWidgets的项目,它说是可以将静态文件,如css,js与python代码一起打包来使用,虽然我一直没有研究过它的代码,但是我猜想与web server的处理方式有关。比如它已经在TurboGears和Pylons中使用了,它们都支持真正的wsgi的方式,因此可以在底层解析时根据url的不同进行静态文件的处理。而Django的哲学或者说是设计方式不同,它不使用真正的wsgi作为底层的机制,它使用自已的Middleware来处理。当然,如果我们在Middleware来处理一样是可以的,但之所以Django不这样做是因为它认为:web server的机制应该会更出色,而django在这方面并不擅长,因此它并不建议由django来做。我想当网站处于生产状态这样是最合理的,但是当你在开发时,这样并不方便,特别是对于重用性并不友好。因此在django中实现象其它的框架一样的分布式的静态资源的管理我认为很有必要。这样开发时可以使用分布式,但在生产部署时采用集中式。

那么怎么做呢?首先我的想法是将静态文件分布到以APP为单位的单元中。可以有两种处理方式:一种方式是开发时继续使用django已经提供了的一个供开发使用的静态文件服务的view模块,不过它不支持在APP中查找静态文件,因此我做了改造,当按原来的方式找不到静态文件时,就去遍历每个APP下的固定目录。这样的话,这种方式是在urls.py中配置即可。同时APP下的固定目录可以在设置urls.py时指定。另一种方式则是做成一个Middleware。前一种我已经实现,后一种没有实现,大同小异。

以openbookplatform中的具体实现为例,在urls.py中的配置为:

(r'^site_media/(.*)$', 'utils.staticview.serve', {'document_root': settings.SITE_MEDIA, 'app_media_folder':'media'}),

staticview.server是我改造后的方法。它除了需要一个与以前的方法一样的document_root参数外,还可以传入一个app_media_folder的方法,这里为media,这样当以前的方式找不到静态文件时,会去每个已经安装的APP下的media目录下去查找相匹配的文件。

然后在你需要放置静态文件的APP下,按照上面app_media_folder的设置创建相应的目录,如果需要子目录也一起创建。这样你也可以创建一个只有静态文件存在的APP。

当在生产运行时,只要再有一个简单的工具将所有APP下的静态目录拷贝到指定的目录下即可。这个工具我还没有开发,但是应该是很简单的。这样生产部署时只要运行这个工具即可。再修改下urls.py的配置将静态文件的处理pattern注释掉就行了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics