user1102171
user1102171

Reputation: 684

applying view decorators to MethodView derived classes

in my flask app all the views are derived from MethodView.

class TestView(MethodView):
def __init__(self):
    self.form = TestForm()

@login_required
@campaign_required
def get(self,cid):
     .........

and the url rule is set in different file.....

Is there something similar possible to django as mentioned in this post:

What's the difference between the two methods of decorating class-based views?

I need to decorate the class with few restrictions...as mentioned above....

Upvotes: 1

Views: 1261

Answers (1)

Serge
Serge

Reputation: 2006

I've written small example based on this snippet:

class BaseApi(MethodView):


def _content_type(self, method):
    """ decorator example """
    def decorator(*args, **kwargs):
        best = request.accept_mimetypes.best_match(['text/html', 'application/json'])

        if best == 'text/html':
            return self._html(*method(*args, **kwargs))

        elif best == 'application/json':
            return self._json(*method(*args, **kwargs))

        else:
            abort(400, err='Unknown accept MIME type - "%s"' % best)
            return

    return decorator

def dispatch_request(self, *args, **kwargs):
    method = super(BaseApi, self).dispatch_request

    if self.method_decorators is None:
        return method(*args, **kwargs)

    method_decorators = self.method_decorators.get(request.method.lower(), [])
    if getattr(method_decorators, '__call__', False):
        method_decorators = [method_decorators]

    common_decorators = self.method_decorators.get('*', [])
    if getattr(common_decorators, '__call__', False):
        common_decorators = [common_decorators]

    method_decorators.extend(common_decorators)

    for decorator in method_decorators:
        method = decorator(self, method)

    return method(*args, **kwargs)

method_decorators = {
    '*': _content_type,   # decorators here are applied to all methods
    # 'get': <another decorator only for get method>,
    # 'post': [<list of decorator functions that are applied for post requests>]
}

Upvotes: 1

Related Questions