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