J’ai l’habitude de travailler avec le Framework Ruby On Rails et il y a un filtre before_filter
sur les contrôleurs qui permet d’exécuter un ensemble de taches avant de lancer une action. C’est utile pour si on veut vérifier qu’un utilisateur s’est bien connecté et a les droits d’exécuter une action par exemple.
Récemment, j’ai commencé à développer une application Django au bureau et je me suis rendu compte que cette fonctionnalité n’existe pas dans cet univers 🙁
Après l’avoir googlé je suis tombé sur un middleware qui permet de le faire sur Django 🙂 (encore merci M. Google).
Voici le middleware en question :
import sys
class BeforeFilterMiddleware(object):
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'):
self.filters = []
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
Utilisation :
J’ai enregistré ce script dans un fichier outils/my_middlewares/before_filter.py
du répertoire principal de mon application.
Ensuite, je l’ai ajouté sur la liste des middlewares de mon application : la constante MIDDLEWARE_CLASSES
du fichier de configuration settings.py
, maintenant il doit ressembler à ca :
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'outils.my_middlewares.before_filter.BeforeFilterMiddleware',
)
C’est tout pour la configuration.
Maintenant si on veut, par exemple, exécuter une fonction admin_required
avant de lancer les actions new
et create
et owner_required
pour l’action edit
il suffit d’ajouter ces lignes de code sur ladite view :
BEFORE_FILTER = {'admin_required': ('new', 'create'),
'owner_required': ('edit',),
}
def admin_required(request, view, args, kwargs):
if not is_admin():
messages.warning(request, u"Vous ne pouvez pas accéder à cette page")
return HttpResponseRedirect(reverse('root'))
def owner_required(request, view, args, kwargs):
if not is_owner():
messages.warning(request, u"Vous ne pouvez pas modifier une ressource qui ne vous appartient pas")
return HttpResponseRedirect(reverse('root'))
C’est tout ! Vous avez des questions ? Commentez 🙂