这篇文章写的比较晚,主要也是要真正用起来才会发现,django1.4的这次升级在项目目录结构,配置文件上都有比较多的调整,恰好这次也受这样的困扰,所以就拿出来和大家分享一下。 django1.4增加了一个很重要的目录: static,在之前,django的所有静态文件都是放在media目录下的,但是同时用户在后台主动上传的文件也会放到这里,所以会引起一些不必要的混乱. 而且在之前的版本种,django的admin会霸占/media的路径,导致我之前不得不在配置里面强制修改一下:
ADMIN_MEDIA_PREFIX = '/admin_media/'
或者让网站自己的静态文件路径使用的别的前缀:
MEDIA_URL = '/site_media/'
对应的nginx.conf也要做一些相应的配置,对于之前版本相关的内容,这篇文章就不做赘述了,有兴趣的朋友可以去我之前写的博文看一下: linux下nginx+python+fastcgi部署总结(django版),PS:当时还没用uwsgi,大家将就一下。。 回到我们说的django1.4的变更,增加的static目录用来存放网站需要的静态文件,如css,img等,而/media目录用来存放用户上传的文件,admin使用的静态文件是放到/static/admin下。 这样的调整是要比原来合理很多,但同时nginx.conf的配置也需要做响应的变更,如:
server { listen 80; server_name test.com; location / { include uwsgi_params; #这样程序触发的返回码,才能被ngx识别 uwsgi_intercept_errors on; uwsgi_pass 127.0.0.1:1999; } location /static/admin/ { alias /usr/local/lib/python2.7/site-packages/django/contrib/admin/static/admin/; #for windows #alias C:/Python27/Lib/site-packages/django/contrib/admin/static/admin/; break; } location /static/ { alias /data/release/platformstatic/; break; } location /media/ { alias /data/release/platformmedia/; break; } }
需要特别说明的是,即使你在django的urls.py里面加了如下配置:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
也只是在使用 manange.py runserver时有效,在用uwsgi或fastcgi都是没有用的,还是需要在nginx.conf指定目录映射才行,这也是django担心有人在正式环境乱配降低django处理性能. 关于静态文件等的配置基本就到这里。 这次django1.4的很多升级感觉都很贴心,这里简单列举一下, 1. mysite.settings目录位置的变更,让大项目的目录结构更规范 2. 支持cookie based session 3. 通用views的升级 OK,django的事情就说到这里。 接下来说说另一个框架bottle的事情。bottle不像flask,默认集成了cookie based session,理由是找不到合适的做法,其实想想也是,session的实现有好多种,如果都实现进来就太臃肿,如果像flask一样只实现一种又面临被替换的危险,所以不如不提供。 感谢开源和通用的wsgi协议,我们可以借助于另外的库来实现这件事情 - beaker beaker具体的使用就不在这里说了,大家可以自己查看文档,只是我觉得每次都要使用如此复杂的代码很让人不爽:
s = request.environ.get('beaker.session') return str(s.get('x', '1'))
所以就在想能不能做的也和flask或django一样,代码像这么简单呢?
data = session.get('x', '1')
这里面有个最主要的问题是bottle的request是个proxy,所以每次要获取session的时候,一定都要实时从request里面获取,否则可能会获取到别人的数据,所以尝试这写了如下代码:
from bottle import request def env_session(): '''get env session''' s = request.environ.get('beaker.session') if not s: raise KeyError('beaker.session is none') return s class SessionWrapper(object): '''docstring for SessionWrapper''' def __init__(self): super(SessionWrapper, self).__init__() def __getattr__(self, key): return env_session().__getattr__(key) def __setattr__(self, key, value): return env_session().__setattr__(key, value) def __getitem__(self, key): return env_session().__getitem__(key) def __setitem__(self, key, value): return env_session().__setitem__(key, value) def __delitem__(self, key): return env_session().__delitem__(key) def __iter__(self): return env_session().__iter__() def __len__(self): return env_session().__len__() session = SessionWrapper()
这样就可以实现了,但是总感觉实现上复杂了一些,所以也是希望拿出来看大家是否有更好的wrapper方法? OK,整篇博文结束~~
TonySeek on #
SessionWrapper 为何不直接用 __getattribute__ 来实现代理呢?
class SessionWrapper(object):
def __getattribute__(self, attr):
return getattr(env_session(), attr)
Reply
Dante on #
不行的。
你可以搜一下 __getattribute__ 和 __getattr__的区别,一个是获取已有的属性,一个是获取没有的属性。
而且你还是得处理 def __getitem__(self, key): 之类的操作,否则在执行:
session['x'] = 1
时,会报错
Reply
玻璃钢模具 on #
我来逛逛,顺便帮博主顶一下,希望博主不嫌弃嘿嘿
Reply
追梦人 on #
django最近正在看呢
Reply