Django是一个自带session功能的python版web框架,session的支持存储方式支持memcache,数据库,文件等;当然最快的自然是memcache了,但是当将django应用部署到bae3上的时候会发现,按默认的配置是无法成功运行起来的,原因是bae3提供的cache是非标准memcache接口;

bae3提供的cache接口与标准接口相比有以下两个差异:

  1. cache初始化时需要提供用户名密码;这个可以理解,因为bae3的cache是分布式的,并非和应用在同一主机,bae需要搞清楚那个应用的cache在哪儿部署着呢。

  2. cache的key值必须是string类型,我用unicode就报错了。

鉴于以上的情况我们需要修改一些django提供的session引擎,就是修改setting.py文件中的“SESSION_ENGINE”为自己的类, 比如我就把它改为“SESSION_ENGINE = 'sd.com.lib.session'”了。具体的sd.com.lib.session的代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#code:utf-8
#
# Copyright(C) 2011 SupDo.com
# Licensed under the GUN License, Version 3.0 (the "License");
# 
# File:        session.py
# Author:      KuKei
# Create Date: 2013-04-17
# Description: Session模块
# Modify Date: 2013-04-17
 
from sd import settings
from django.contrib.sessions.backends.base import SessionBase, CreateError
try:
    from bae_memcache.cache import BaeMemcache as cache
except Exception:
    from django.core.cache import cache
 
KEY_PREFIX = "sessions"
 
 
class SessionStore(SessionBase):
 
    """
    A cache-based session store.
    """
    def __init__(self, session_key=None):
        try:
            self._cache =  cache(settings.BAE_CACHE_ID, settings.BAE_CACHE_ADR, settings.BAE_API_KEY, settings.BAE_SECRET_KEY)
        except Exception:
            self._cache = cache
        if session_key:
            session_key = session_key.encode('utf-8')
        super(SessionStore, self).__init__(session_key)
 
    @property
    def cache_key(self):
        return KEY_PREFIX + self._get_or_create_session_key().encode('utf-8')
 
    def load(self):
        try:
            #session_data = self._cache.get(self.cache_key, None)
            session_data = self._cache.get(self.cache_key.encode('utf-8'))
        except Exception:
            # Some backends (e.g. memcache) raise an exception on invalid
            # cache keys. If this happens, reset the session. See #17810.
            session_data = None
        if session_data is not None:
            return session_data
        self.create()
        return {}
 
    def create(self):
        # Because a cache can fail silently (e.g. memcache), we don't know if
        # we are failing to create a new session because of a key collision or
        # because the cache is missing. So we try for a (large) number of times
        # and then raise an exception. That's the risk you shoulder if using
        # cache backing.
        for i in xrange(10000):
            self._session_key = self._get_new_session_key().encode('utf-8')
            try:
                self.save(must_create=True)
            except CreateError:
                continue
            self.modified = True
            return
        raise RuntimeError("Unable to create a new session key.")
 
    def save(self, must_create=False):
        if must_create:
            func = self._cache.add
        else:
            func = self._cache.set
        result = func(self.cache_key.encode('utf-8'),
                      self._get_session(no_load=must_create),
                      self.get_expiry_age())
        if must_create and not result:
            raise CreateError
 
    def exists(self, session_key):
        #return (KEY_PREFIX + session_key) in self._cache
        return True if self._cache.get(KEY_PREFIX + session_key.encode('utf-8')) else False
 
    def delete(self, session_key=None):
        if session_key is None:
            if self.session_key is None:
                return
            session_key = self.session_key
        self._cache.delete(KEY_PREFIX + session_key.encode('utf-8'))

这样就能正常使用django上的用cache存储的session了。

注意:

bae3上cache的入口参数SECRET_KEY如果要定义在setting中的话,不要和setting自己的SECRET_KEY冲突了,要不会报密码错误之类的提示的。这个是我调试时遇到的问题。
好了,这个方法希望对你有用。