import sys class BeforeFilter(object): """ Middleware component for performing actions before calling views. To use, define BEFORE_FILTER in your application's views.py. BEFORE_FILTER should be a dictionary mapping a filter function to a list/tuple of view functions:: BEFORE_FILTER = {'check_trailing_slash': ('index', 'detail')} To have *all* view functions filtered, simply leave the tuple blank:: BEFORE_FILTER = {'authenticate': ()} To exclude a view from being filtered prefix it with dash:: BEFORE_FILTER = {'authenticate': ('-index', '-detail')} If you require filters to be applied in a specific order, use Django's SortedDict:: from django.utils.datastructures import SortedDict BEFORE_FILTER = SortedDict() BEFORE_FILTER['authenticate'] = ('-index', '-detail') BEFORE_FILTER['get_messages'] = () """ def __init__(self): self.setting = 'BEFORE_FILTER' self.filters = [] def _call_filters(self, request, view, args, kwargs): response = None for f in self.filters: response = f(request, view, args, kwargs) if response and response.has_header('location'): return response self.filters = [] return response def process_view(self, request, view, args, kwargs): module = sys.modules[view.__module__] if hasattr(module, self.setting): for func, views in getattr(module, self.setting).items(): exclude = '-%s' % view.func_name if not views or view.func_name in views or views and \ exclude not in views: if hasattr(module, func): if getattr(module, func) not in self.filters: self.filters.append(getattr(module, func)) if self.filters: return self._call_filters(request, view, args, kwargs) return None