【问题标题】:Bottle.py session with Beaker与烧杯的 Bottle.py 会话
【发布时间】:2012-11-23 23:50:06
【问题描述】:

第一次在这里提问。

我目前正在努力研究如何使用 Bottle 微框架正确使用 Beaker。这是有问题的程序:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# filename: server.py

import bottle as app
from beaker.middleware import SessionMiddleware

session_options = {
    'session.type': 'file',
    'session.data_dir': './session/',
    'session.auto': True,
}
app_middlware = SessionMiddleware(app.app(), session_options)
app_session = app.request.environ.get('beaker.session')

@app.route('/login')
def login():
    app_session = app.request.environ.get('beaker.session')
    app_session['logged_in'] = True

@app.route('/logout')
def logout():
    app_session = app.request.environ.get('beaker.session')
    if app_session.get('logged_in'):
        app_session['logged_in'] = False
        return 'You are logged out'
    app.redirect('/login')

@app.route('/dashboard')
def dashboard():
    app_session = app.request.environ.get('beaker.session')
    if app_session.get('logged_in'):
        return 'You are logged in'
    app.redirect('/login')

app.debug(True)
app.run(app=app_middlware, reloader=True)

如果你注意到了,我会继续在每个 def 块上调用 app_session = app.request.environ.get('beaker.session'),这样它就不会返回如下错误:TypeError: 'NoneType' object does not support item assignment --- 似乎 Python 无法识别其函数之外的变量(如果我错了,请纠正我)。

以下是问题:

  1. 我应该怎么做才能只有一个 app_session = app.request.environ.get('beaker.session') 实例,以便它可以用于每个 def 块(我真的需要一个实例,因为要检查和使用同一个会话)。
  2. 如果这是唯一的方法(虽然它很丑),那么我是否应该将所有需要会话的路由组合起来,以便实现app_session 的单个实例?

类似:

@app.route('/<path:re:(login|dashboard|logout)\/?>')
def url(path):
    app_session = app.request.environ.get('beaker.session')
    if 'login' in path:
        app_session['logged_in'] = True
    elif 'logout' in path:
        if app_session.get('logged_in'):
            # app_session.delete() it doesn't seem to work?
            app_session['logged_in'] = False
            return 'You are logged out'
        app.redirect('/login')
    elif 'dashboard' in path:
        if app_session.get('logged_in'):
            return 'You are logged in'
        app.redirect('/login')

【问题讨论】:

  • 那么当您不在每个视图函数中重新定义app_session 并且只使用全局范围内的那个时会发生什么?
  • 它返回一个错误,像这样:File "server.py", line 14, in login app_session['logged_in'] = True TypeError: 'NoneType' object does not support item assignment
  • 对不起 Blender,但在发布问题之前我已经这样做了。并且SessionMiddleware(app, session_options) 也会导致错误,它应该是SessionMiddleware(app.app(), session_options)
  • 因为这样的问题我切换到了 Flask... 最后一次尝试:尝试使用 app_middleware.session 而不是 app.session 看看是否有帮助。

标签: python bottle beaker


【解决方案1】:

在您的bottle 应用程序中使用beaker 很容易。首先,设置您的 Bottle 应用:

import bottle
from bottle import request, route, hook
import beaker.middleware

session_opts = {
    'session.type': 'file',
    'session.data_dir': './session/',
    'session.auto': True,
}

app = beaker.middleware.SessionMiddleware(bottle.app(), session_opts)

后来:

bottle.run(app=app)

有了这个,每次您收到请求时,您的 Beaker 会话都将作为 request.environ['beaker_session']。为了方便,我通常会这样做:

@hook('before_request')
def setup_request():
    request.session = request.environ['beaker.session']

这安排在处理任何请求之前运行setup_request;我们正在使用bottle.request 变量(参见前面的导入语句),它是一个线程局部变量,包含有关当前请求的信息。从现在开始,我可以在需要时参考request.session,例如:

@route('/')
def index():
    if 'something' in request.session:
       return 'It worked!'

    request.session['something'] = 1

【讨论】:

  • 谢谢拉斯克斯! @hook('before_request') 成功了。 :D
猜你喜欢
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
相关资源
最近更新 更多