在Django中有一个设置文件,用于定义要在每个请求上运行的中间件.此中间件设置是全局的.有没有办法在每个视图的基础上指定一组中间件?我希望特定的URL使用一组与全局集不同的中间件.
你想要的decorator_from_middleware
.
from django.utils.decorators import decorator_from_middleware @decorator_from_middleware(MyMiddleware) def view_function(request): #blah blah
它不适用于URL,但它适用于每个视图,因此您可以对其效果进行细粒度控制.
我对这个问题有一个真正的解决方案.警告; 这有点像黑客.
""" 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
编辑:删除了两次运行视图的先前版本.
这是我最近用来解决你在对Ned的回答的评论中提出的场景的解决方案......
它假定:
A)这是一个自定义中间件,或者您可以使用自己的中间件类扩展/包装的中间件
B)你的逻辑可以等到,process_view
而不是process_request
,因为process_view
你可以view_func
在解决后检查参数.(或者您可以调整以下代码以使用urlresolvers
Ignacio指示).
# settings.py EXCLUDE_FROM_MY_MIDDLEWARE = set('myapp.views.view_to_exclude', 'myapp.views.another_view_to_exclude') # some_middleware.py from django.conf import settings def process_view(self, request, view_func, view_args, view_kwargs): # Get the view name as a string view_name = '.'.join((view_func.__module__, view_func.__name__)) # If the view name is in our exclusion list, exit early exclusion_set = getattr(settings, 'EXCLUDE_FROM_MY_MIDDLEWARE', set()) if view_name in exclusion_set: return None # ... middleware as normal ... # # Here you can also set a flag of some sort on the `request` object # if you need to conditionally handle `process_response` as well.
可能有一种方法可以进一步推广这种模式,但这很好地完成了我的目标.
为了回答您更普遍的问题,我认为Django库中没有任何东西可以帮助您解决这个问题.如果django-users邮件列表尚未在那里解决,那将是一个很好的话题.