最后更新于 .

这篇文章写的比较晚,主要也是要真正用起来才会发现,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,整篇博文结束~~

Pingbacks

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. TonySeek

    TonySeek on #

    SessionWrapper 为何不直接用 __getattribute__ 来实现代理呢?

    class SessionWrapper(object):

    def __getattribute__(self, attr):
    return getattr(env_session(), attr)

    Reply

    1. Dante

      Dante on #

      不行的。

      你可以搜一下 __getattribute__ 和 __getattr__的区别,一个是获取已有的属性,一个是获取没有的属性。

      而且你还是得处理 def __getitem__(self, key): 之类的操作,否则在执行:
      session['x'] = 1
      时,会报错

      Reply

  2. 玻璃钢模具

    玻璃钢模具 on #

    我来逛逛,顺便帮博主顶一下,希望博主不嫌弃嘿嘿

    Reply

  3. 追梦人

    追梦人 on #

    django最近正在看呢

    Reply

发表评论