В Django есть файл настроек, который определяет промежуточное программное обеспечение для каждого запроса. Это промежуточное ПО является глобальным. Есть ли способ указать набор промежуточного программного обеспечения для каждого представления? Я хочу, чтобы определенные URL-адреса использовали набор промежуточного программного обеспечения, отличный от глобального набора.
Неглобальное промежуточное ПО в Django
Ответ 1
Вы хотите decorator_from_middleware
.
from django.utils.decorators import decorator_from_middleware
@decorator_from_middleware(MyMiddleware)
def view_function(request):
#blah blah
Он не применяется к URL-адресам, но он работает для каждого просмотра, поэтому вы можете иметь мелкомасштабный контроль над его эффектом.
Ответ 2
Здесь решение, которое я использовал недавно для рассмотрения сценария, который вы представили в комментарии к 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, если он еще не был рассмотрен там.
Ответ 3
У меня есть реальное решение этой проблемы. Предупреждение; это немного взломать.
""" 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
Изменить: удалена предыдущая версия, которая дважды запускала представление.
Ответ 4
Используйте django.core.urlresolvers.resolve()
против request.path
в оболочке для промежуточного программного обеспечения, чтобы попытаться увидеть, находится ли это представление в приложении, и пропустите обработку, если это так.
Ответ 5
Лучшее, что мне удалось найти, это использовать, если request.path_info.startswith('...') пропустить промежуточное программное обеспечение, просто вернув запрос. Теперь вы можете создать промежуточное программное обеспечение только для пропусков, а затем наследовать это. Возможно, вы могли бы сделать что-то еще более простое и сохранить этот список в своих settings.py, а затем пропустить все это. Если я ошибаюсь, дайте мне знать.
Ответ 6
Вы можете использовать метод process_view, который вызывается перед вызовом функции func. В process_view вы можете проверить - если это представление требует этого промежуточного перехвата.
Ответ 7
Django urlmiddleware позволяет применять промежуточное программное обеспечение только для представлений, сопоставленных определенным URL-адресам.