2010-05-26 4 views
29

В Django есть файл настроек, который определяет промежуточное программное обеспечение, которое будет выполняться при каждом запросе. Это промежуточное ПО является глобальным. Есть ли способ указать набор промежуточного программного обеспечения для каждого представления? Я хочу, чтобы определенные URL-адреса использовали набор промежуточного программного обеспечения, отличный от глобального набора.Неглобальное промежуточное программное обеспечение в Django

ответ

32

Вы хотите decorator_from_middleware.

from django.utils.decorators import decorator_from_middleware 

@decorator_from_middleware(MyMiddleware) 
def view_function(request): 
    #blah blah 

Это не относится к URL-адресам, но он работает на просмотр, так что вы можете иметь мелкозернистую контроль над своим эффектом.

+8

Хорошо, но что, если я хочу, чтобы исключить промежуточное программное обеспечение вместо того, чтобы добавить их. Например, в моем файле настроек перечислены middleware MIDDLEWARE_CLASSES = ('A', 'B', 'C'), и я хочу, чтобы один вид имел A и B, но не C. Есть ли декоратор для удаления промежуточного программного обеспечения?Этот пользовательский материал промежуточного слоя необходим только в одном приложении Django, поэтому я не хочу добавлять 'decorator_from_middleware' ко всем другим представлениям в моем приложении. – hekevintran

+2

'@ csrf_exempt', который делает что-то похожее на то, что вы просите, работает, установив флаг в представлении, который затем проверяется соответствующим промежуточным программным обеспечением CSRF. Конечно, не общее решение, а просто замечание. – sfridman

1

Используйте django.core.urlresolvers.resolve() против request.path в обертке для промежуточного программного обеспечения, чтобы попытаться посмотреть, есть ли представление в приложении, и пропустить обработку, если это так.

+0

Так что я должен использовать оператор if в моем коде промежуточного программного обеспечения, чтобы заставить его пропускать в определенных приложениях? – hekevintran

+0

В оболочке, а не в промежуточном программном обеспечении. –

+0

Что такое оболочка для промежуточного программного обеспечения? – hekevintran

5

Вот решение, которое я использовал в последнее время для решения сценария вы представили в комментарии к ответу Неда ...

Это предполагает, что:

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, если он еще не был рассмотрен там.

5

У меня есть реальное решение этой проблемы. Предупреждение; это немного взломать.

""" 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 

Редактировать: удалена предыдущая версия, которая дважды запустила представление.

0

Django urlmiddleware позволяет применять промежуточное программное обеспечение только к представлениям, которые сопоставляются определенным URL-адресам.

+0

Хорошее приложение, однако, оно по-прежнему добавляет глобальное промежуточное программное обеспечение, которое проверяет запрашиваемый URL-адрес на любое настроенное промежуточное программное обеспечение URL-адреса: https://github.com/d0ugal/django-urlmiddleware/blob/master/urlmiddleware/middleware.py#L18 – rednaw

1

Лучшее, что мне удалось найти, это использовать, если request.path_info.startswith ('...'), чтобы пропустить промежуточное программное обеспечение, просто вернув запрос. Теперь вы можете создать промежуточное программное обеспечение только для пропусков, а затем наследовать это. Возможно, вы могли бы сделать что-то еще более простое и сохранить этот список в своих settings.py, а затем пропустить все это. Если я ошибаюсь, дайте мне знать.

1

Вы можете использовать метод process_view, который вызывается перед вызовом функции func. В process_view вы можете проверить - если это представление требует этого промежуточного перехвата.

0

Я думаю, что это простой способ, чтобы исключить вид из промежуточного

from django.core.urlresolvers import resolve 
current_url = resolve(request.path_info).url_name 

if want to exclude url A, 

class your_middleware: 
    def process_request(request): 
     if not current_url == 'A': 
      "here add your code" 
Смежные вопросы