I think my problem is related on the way I structured my pyramid project. What I want to accomplish is to make my code runs on all views, I don't want to paste same codes on all views. Its like I will include the code in all views by just simply calling it. This is my code.
my wizard module
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)
my bill module
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)
As you can see I have to paste this code twice (this code checks if session exist, if not, then redirect user to login page)
session = self.request.session
if session:
return {'fullname':session['name'],'userrole':session['userrole']}
else:
url = self.request.route_url('login')
return HTTPFound(location=url)
I've tried to search and I think what I need is some sort of auto loader? How can I apply this on pyramid? Or should I stick with this process?
If you wish to return exactly the same thing from both (many) views, then the best way is to use inheritance.
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)
Use generic_response
in WizardView
and BillView
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()
If you want to just check (and redirect) when session does not exists and otherwise proceed normally you could use custom exceptions and corresponding views.
First define custom exception
class SessionNotPresent(Exception):
pass
And view for this exception
@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)
Then just check if session exists in parent constructor
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
In views simply extend SessionView
and non existing sessions will be handeled by 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']}
You could easily add additional parameters to exception (redirect_url
, ...)
For exception handling see http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/pylons/exceptions.html