From 68bed38dc2b46a83436ba4f6d8a902915bcb85a5 Mon Sep 17 00:00:00 2001 From: Julien Castets Date: Fri, 17 Jan 2014 11:35:44 +0100 Subject: [PATCH] FlaskView.decorators can be generated from a classmethod --- README.rst | 14 ++++++++++++++ flask_classy.py | 9 ++++++--- test_classy/test_decorators.py | 13 ++++++++++--- test_classy/view_classes.py | 23 +++++++++++++++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 3dcbdd5..7c33214 100644 --- a/README.rst +++ b/README.rst @@ -548,6 +548,20 @@ method and `Flask-Classy` will take care of the rest:: def so_is_this(self): return "Looking at me? I guess you're logged in." +You can also override the classmethod `get_decorators`:: + + class WhataGreatView(FlaskView): + + @classmethod + def get_decorators(cls): + return [login_required] + + def this_is_secret(self): + return "If you see this, you're logged in." + + def so_is_this(self): + return "Looking at me? I guess you're logged in." + Before and After ---------------- diff --git a/flask_classy.py b/flask_classy.py index 440b0c3..66b2780 100644 --- a/flask_classy.py +++ b/flask_classy.py @@ -66,6 +66,10 @@ class FlaskView(_FlaskViewBase): route_prefix = None trailing_slash = True + @classmethod + def get_decorators(cls): + return cls.decorators + @classmethod def register(cls, app, route_base=None, subdomain=None, route_prefix=None, trailing_slash=None): @@ -190,9 +194,8 @@ def make_proxy_method(cls, name): i = cls() view = getattr(i, name) - if cls.decorators: - for decorator in cls.decorators: - view = decorator(view) + for decorator in cls.get_decorators(): + view = decorator(view) @functools.wraps(view) def proxy(**forgettable_view_args): diff --git a/test_classy/test_decorators.py b/test_classy/test_decorators.py index 81db83f..35fe622 100644 --- a/test_classy/test_decorators.py +++ b/test_classy/test_decorators.py @@ -1,9 +1,12 @@ from flask import Flask, url_for -from .view_classes import DecoratedView +from .view_classes import (DecoratedView, AutoDecoratedView, + OverridenAutoDecoratedView) from nose.tools import * app = Flask("decorated") DecoratedView.register(app) +AutoDecoratedView.register(app) +OverridenAutoDecoratedView.register(app) client = app.test_client() @@ -47,6 +50,10 @@ def test_recursive_with_route_with_parameter(): eq_(b"Anotherval 1234", resp.data) +def test_autodecorated(): + resp = client.get('/autodecorated/') + eq_(b"foobar", resp.data) - - +def test_overriden_autodecorated(): + resp = client.get('/overridenautodecorated/') + eq_(b"foobar", resp.data) diff --git a/test_classy/view_classes.py b/test_classy/view_classes.py index 3b87ad1..a6ea108 100644 --- a/test_classy/view_classes.py +++ b/test_classy/view_classes.py @@ -230,6 +230,29 @@ def anotherval(self, val): return "Anotherval " + val +def foo_decorator(func): + @wraps(func) + def wrapped(*args, **kwargs): + return 'foo' + func(*args, **kwargs) + return wrapped + + +class AutoDecoratedView(FlaskView): + decorators = [foo_decorator] + + def index(self): + return 'bar' + + +class OverridenAutoDecoratedView(FlaskView): + + @classmethod + def get_decorators(cls): + return [foo_decorator] + + def index(self): + return 'bar' + class InheritanceView(BasicView):