如何在不将会话代码放在金字塔的所有视图上的情况下将会话放在所有页面上?

How to put sessions on all pages without putting the session code on all views in pyramid?

我认为我的问题与我构建金字塔项目的方式有关。 我想要完成的是让我的代码在所有视图上运行,我不想在所有视图上粘贴相同的代码。就像我将通过简单地调用它来将代码包含在所有视图中一样。这是我的代码。

我的向导模块

from pyramid.view import view_config, view_defaults
from .models import *
from datetime import datetime
from pyramid.response import Response
from bson import ObjectId
from pyramid.httpexceptions import HTTPFound
import json

class WizardView:

def __init__(self, request):
    self.request = request

@view_config(route_name='wizard', renderer='templates/wizard.jinja2')
def wizard(self):
    session = self.request.session
    if session:
        return {'fullname':session['name'],'userrole':session['userrole']}
    else:
        url = self.request.route_url('login')
        return HTTPFound(location=url)

我的账单模块

from pyramid.view import view_config, view_defaults
from .models import *
from datetime import datetime
from pyramid.response import Response
from bson import ObjectId 
from pyramid.httpexceptions import HTTPFound

class BillView:

def __init__(self, request):
    self.request = request

@view_config(route_name='bills', renderer='templates/bills.jinja2')
def bills(self):
    session = self.request.session
    if session:
        return {'fullname':session['name'],'userrole':session['userrole']}
    else:
        url = self.request.route_url('login')
        return HTTPFound(location=url)

如您所见,我必须将此代码粘贴两次(此代码检查会话是否存在,如果不存在,则将用户重定向到登录页面)

session = self.request.session
if session:
    return {'fullname':session['name'],'userrole':session['userrole']}
else:
    url = self.request.route_url('login')
    return HTTPFound(location=url)

我试过搜索,我想我需要的是某种自动装载机?我怎样才能把它应用到金字塔上?还是我应该坚持这个过程?

如果您希望return从两个(多个)视图中得到完全相同的东西,那么最好的方法是使用继承。

class GenericView:
    def __init__(self, request):
    self.request = request

    def generic_response(self):
        session = self.request.session
        if session:
            return {'fullname':session['name'],'userrole':session['userrole']}
        else:
            url = self.request.route_url('login')
            return HTTPFound(location=url)

WizardViewBillView

中使用generic_response
class WizardView(GenericView):

    def __init__(self, request):
        super().__init__(request)
        # Do wizard specific initialization

    @view_config(route_name='wizard', renderer='templates/wizard.jinja2')
    def wizard(self):
        return self.generic_response()

class BillView(GenericView):

    def __init__(self, request):
        super().__init__(request)
        # Do bill specific initialization

    @view_config(route_name='bills', renderer='templates/bills.jinja2')
    def bills(self):
        return self.generic_response()

如果您只想在会话不存在时检查(并重定向),否则可以正常进行,您可以使用自定义异常和相应的视图。

首先定义自定义异常

class SessionNotPresent(Exception):
    pass

并查看此异常

@view_config(context=SessionNotPresent)
def handle_no_session(context, request):
     # context is our custom exception, request is normal request
     request.route_url('login')
     return HTTPFound(location=url)

然后检查父构造函数中是否存在session

class SessionView:
    def __init__(self, request):
        self.request = request
        if not self.request.session:
            raise SessionNotPresent() # Pyramid will delegate request handilng to handle_no_request

在视图中只需扩展 SessionView,不存在的会话将由 handle_no_session 处理。

class WizardView(SessionView):

    def __init__(self, request):
        super().__init__(request)
        # Do wizard specific initialization

    @view_config(route_name='wizard', renderer='templates/wizard.jinja2')
    def wizard(self):
        session = self.request.session
        return {'fullname':session['name'],'userrole':session['userrole']}


class BillView(SessionView):

    def __init__(self, request):
        super().__init__(request)
        # Do bill specific initialization

    @view_config(route_name='bills', renderer='templates/bills.jinja2')
    def bills(self):
        session = self.request.session
        return {'fullname':session['name'],'userrole':session['userrole']}

您可以轻松地向异常添加额外的参数 (redirect_url, ...)

异常处理见http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/pylons/exceptions.html

您可以使用事件:http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/events.html

示例:

from pyramid.events import subscriber, NewRequest
@subscriber(NewRequest)
def check_session(event):
    if not event.request.session:
        raise HTTPFound(location=event.request.route_path('login'))