Login

CBV decorator from view function decorator

Author:
powderflask
Posted:
October 3, 2017
Language:
Python
Version:
1.10
Score:
0 (after 0 ratings)

The Mixin approach for applying permissions to CBV views suffers from 3 issues:

  1. you need to read the code to see what permissions are being applied to a View
  2. multiple bits of disparate code required to specify, e.g., a simple permission check
  3. permissions set on a base class are overridden by permission set on sub-class, unless special care is taken

Here's a nice trick, using only built-in django machinery, apply a decorator intended to decorate a django view function to a CBV view. https://docs.djangoproject.com/en/1.11/topics/class-based-views/intro/#decorating-the-class

This approach works for any function decorators with arguments - simply wrap it in a function that takes the same arguments:

def my_cbv_decorator(*args **kwargs):
    return method_decorator(a_view_function_decorator(*args, **kwargs), name='dispatch')

Use your new CBV decorator to decorate View sub-classes:

@my_cbv_decorator('some_parameter')
class MyCBView(django.views.generic.TemplateView):
     pass  # dispatch method for this view is now wrapped by a_view_function_decorator

Note: you can also pass decorator parameter directly to method_decorator, but wrapping it up like this makes the code read nicer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from django.utils.decorators import method_decorator
from django.contrib.auth import decorators

def permission_required(permission):
    """ 
        Returns a decorator that wraps a CBV with a permissions check .
    """
    return method_decorator(decorators.permission_required(permission), name="dispatch")

@permisson_required('some_permission')
class MyCBView(django.views.generic.TemplateView):
     pass  # dispatch method for this view is now wrapped by auth.decorators.permission_required

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.