Extending url-route-view logic
The silly simple example. Let's show view only for user whos are admins.
Flasks Patterns suggest to create a new decorator for such need or use an existing one (roles_required):
def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): if g.user is None: return redirect(url_for('login', next=request.url)) return f(*args, **kwargs) return decorated_function @app.route('/dashboard') @login_required @roles_required('admin', 'editor') def dashboard(): return 'Dashboard'
View level access control done via using mixins or a decorators.
class WorkflowStateMixin(object): def dispatch(self, request, *args, **kwargs): pass class MyView(AdminAllowedMixin,WorkflowStateMixin,...): # TestAdminAllowedMixin as result pass @login_required def my_view(request): pass
mixins have a lot of down-sides but it's very common practice in Django.
Except the mixins and new decorators approach, Pyramid provides a concept of route predicates. You can use existing one or create new, so no mixins or additional decorators are actually required.
# use case @view_config(..., user_role="admin") def view(self): ... @view_config(..., user_role=not_("admin"), method="get", xhr=True, csfr=False) def view(self): ... # predicate definition class UserRolePredicate(object): def __init__(self, val, config): self.val = val def __call__(self, context, request): return request.user.role == self.val ... # configurator part config.add_view_predicate('user_role', UserRolePredicate) ...
But there actually are 'effective_principals' and 'permission' predicates existss for handling access to views in a proper way.
mixins aren't that good approach (which comes from problem of inheritance approach) it depends on your class internals and so requires more testing. Decorator has advantage that it's not depended on view internals and cannot be affected by view code that easily, but in case of lot logic you would be required to use lot of different decorators what makes code more buggy (order of decorators matters) and grumpy. Nice way if view declaration function/decorator that allows its functionality extending.