Ticket #17795: example_code.py

File example_code.py, 3.6 KB (added by ed.crewe@…, 13 years ago)

example decorator needing objects and monkeypatches to provide this

Line 
1#### Example use case: object permission check wrapper for view classes
2
3# This can be wrapped at a class level to provide a simple @permissions(perms_list)
4# decorator for class views that can be used to check request user for
5# permissions on the objects returned by the view
6
7def func_permissions(*perms):
8 """ Class function decorator to check user for object permissions
9 User must have all the permissions listed to get access.
10 """
11 def decorator(view_func):
12 @wraps(view_func, assigned=available_attrs(view_func))
13 def _inner(request=None, *args, **kwargs):
14 """ when decorating a class view_func is get_context_data
15 NB: requires dispatch decorator to set request.user in kwargs
16 """
17 obj_list = kwargs.get('object_list', [])
18 context = view_func(**kwargs)
19 if not obj_list:
20 obj = context.get('subobject',
21 context.get('object', None))
22 if obj:
23 obj_list = [obj, ]
24 user = kwargs.get('user', context.get('user', None))
25 if not user:
26 raise Denied("""No user has been passed in kwargs or context
27 to test %s permissions""" % str(perms))
28 if not obj_list:
29 raise Denied("""There is no object supplied in the request
30 to test %s permissions""" % str(perms))
31 for codename in perms:
32 for obj in obj_list:
33 if not has_permission(obj, user, codename):
34 raise Denied("""User '%s' doesn't have permission
35 '%s' for object '%s' (%s)"""
36 % (user, codename, obj, obj.__class__.__name__))
37 return view_func(*args, **kwargs)
38 return _inner
39 return decorator
40
41############## Monkey patch view classes to pass kwargs for decorators #####
42
43def processformview_get(self, request, *args, **kwargs):
44 form_class = self.get_form_class()
45 form = self.get_form(form_class)
46 kwargs['form'] = form
47 context = self.get_context_data(**kwargs)
48 return self.render_to_response(context)
49
50def baselistview_get(self, request, *args, **kwargs):
51 self.object_list = self.get_queryset()
52 allow_empty = self.get_allow_empty()
53 if not allow_empty and len(self.object_list) == 0:
54 raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
55 % {'class_name': self.__class__.__name__})
56 kwargs['object_list'] = self.object_list
57 context = self.get_context_data(**kwargs)
58 return self.render_to_response(context)
59
60def basedetailview_get(self, request, *args, **kwargs):
61 self.object = self.get_object()
62 kwargs['object'] = self.object
63 context = self.get_context_data(**kwargs)
64 return self.render_to_response(context)
65
66def basedatelistview_get(self, request, *args, **kwargs):
67 self.date_list, self.object_list, extra_context = self.get_dated_items()
68 kwargs['object_list'] = self.object_list
69 kwargs['date_list'] = self.date_list
70 context = self.get_context_data(**kwargs)
71 context.update(extra_context)
72 return self.render_to_response(context)
73
74from django.views.generic.edit import ProcessFormView
75ProcessFormView.get = processformview_get
76from django.views.generic.list import BaseListView
77BaseListView.get = baselistview_get
78from django.views.generic.detail import BaseDetailView
79BaseDetailView.get = basedetailview_get
80from django.views.generic.dates import BaseDateListView
81BaseDateListView.get = basedatelistview_get
82
83
Back to Top