Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-global middleware in Django

In Django there is a settings file that defines the middleware to be run on each request. This middleware setting is global. Is there a way to specify a set of middleware on a per-view basis? I want to have specific urls use a set of middleware different from the global set.

like image 681
hekevintran Avatar asked May 26 '10 21:05

hekevintran


People also ask

What is the middleware in Django?

Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering Django's input or output. Each middleware component is responsible for doing some specific function.

Is middleware a decorator?

Middleware and decorators are similar and can do the same job. They provide a means of inserting intermediary effects either before or after other effects downstream in the chain/stack.


2 Answers

You want decorator_from_middleware.

from django.utils.decorators import decorator_from_middleware  @decorator_from_middleware(MyMiddleware) def view_function(request):     #blah blah 

It doesn't apply to URLs, but it works per-view, so you can have fine-grained control over its effect.

like image 166
Ned Batchelder Avatar answered Oct 04 '22 16:10

Ned Batchelder


I have a real solution for this issue. Warning; it's a little bit of a hack.

""" Allows short-curcuiting of ALL remaining middleware by attaching the @shortcircuitmiddleware decorator as the TOP LEVEL decorator of a view.  Example settings.py:  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',      # THIS MIDDLEWARE     'myapp.middleware.shortcircuit.ShortCircuitMiddleware',      # SOME OTHER MIDDLE WARE YOU WANT TO SKIP SOMETIMES     'myapp.middleware.package.MostOfTheTimeMiddleware',      # MORE MIDDLEWARE YOU WANT TO SKIP SOMETIMES HERE )  Example view to exclude from MostOfTheTimeMiddleware (and any subsequent):  @shortcircuitmiddleware def myview(request):     ...  """  def shortcircuitmiddleware(f):     """ view decorator, the sole purpose to is 'rename' the function     '_shortcircuitmiddleware' """     def _shortcircuitmiddleware(*args, **kwargs):         return f(*args, **kwargs)     return _shortcircuitmiddleware  class ShortCircuitMiddleware(object):     """ Middleware; looks for a view function named '_shortcircuitmiddleware'     and short-circuits. Relies on the fact that if you return an HttpResponse     from a view, it will short-circuit other middleware, see:     https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-request      """     def process_view(self, request, view_func, view_args, view_kwargs):         if view_func.func_name == "_shortcircuitmiddleware":             return view_func(request, *view_args, **view_kwargs)         return None 

Edit: removed previous version that ran the view twice.

like image 34
Chase Seibert Avatar answered Oct 04 '22 14:10

Chase Seibert