Login

Auto-resolving a specific object from key string in url with decorator

Author:
achimnol
Posted:
July 6, 2009
Language:
Python
Version:
1.0
Score:
0 (after 0 ratings)

If you use decorators to views, it will greatly improve readability and extensibility of your code. I'm using a couple of decorators like this to reduce complexity and redundancy in my view codes.

wraps from Python 2.5's standard library make the attributes (name, docstring, and etc) of the decorated function same to those of view_func so that it could be easily recognized when you run ./manage.py show_urls or debug.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# In urls.py

urlpatterns = ('myproject.myapp.views',
    url('^(?P<url_key>[a-z0-9]+)/view/$', 'my_view'),
    url('^(?P<url_key>[a-z0-9]+)/write/$', 'my_write'),
    ...
)



# In views.py

# Requires Python 2.5 or higher
from functools import wraps
from django.shortcuts import get_object_or_404
from django.core.exceptions import PermissionDenied

def object_context(view_func):
    @wraps(view_func)
    def decorated(request, url_key, *args, **kwargs):
        # Put your own discovery conditions here.
        instance = get_object_or_404(MyModel, url_key=url_key, is_active=True)
        return view_func(request, instance, *args, **kwargs)
    return decorated

# For those who use granular pemission systems.
def object_perm_required(*perm_names):
    def decorate(view_func):
        @wraps(view_func)
        @object_context
        def decorated(request, instance, *args, **kwargs):
            for perm_name in perm_names:
                # Put your permission check routine here.
                if request.user.has_row_perm(instance, perm_name):
                    break
            else:
                raise PermissionDenied()
            return view_func(request, instance, *args, **kwargs)
        return decorated
    return decorate

@object_context
def my_view(request, instance):
    # do something

@object_permission_required('can_write')
def my_write(request, instance):
    # do something

More like this

  1. A wrapper around cache_page making it optional by rixx 2 days, 6 hours ago
  2. Treat empty value on DateRangeFilter as a filter for non filled dates by kmmbvnr 1 month, 1 week ago
  3. Django Settings Assignment Expressions aka Walrus Operator example by webology 2 months, 1 week ago
  4. codigo alto nivel by MrRocklion 4 months, 1 week ago
  5. Load template from specific app by Krzysiek555 4 months, 4 weeks ago

Comments

achimnol (on July 6, 2009):

@david_bgk: That's great! Well, there should be some kind of global collective unconsciousness. :P

#

Please login first before commenting.