En Django hay un archivo de configuración que define el middleware que se ejecutará en cada solicitud. Esta configuración de middleware es global. ¿Hay alguna manera de especificar un conjunto de middleware por vista? Quiero que las URL específicas usen un conjunto de middleware diferente del conjunto global.Middleware no global en Django
Respuesta
Quiere decorator_from_middleware
.
from django.utils.decorators import decorator_from_middleware
@decorator_from_middleware(MyMiddleware)
def view_function(request):
#blah blah
No se aplica a las direcciones URL, pero funciona por visión, por lo que puede tener un control preciso sobre su efecto.
Utilice django.core.urlresolvers.resolve()
contra request.path
en un contenedor para que el middleware intente ver si la vista está dentro de la aplicación, y omita el procesamiento si es así.
Entonces, ¿debo usar una instrucción if en mi código de middleware para forzarlo a saltear ciertas aplicaciones? – hekevintran
En el contenedor, no el middleware en sí. –
¿Qué es un ejemplo de un contenedor para middleware? – hekevintran
Aquí hay una solución Recientemente he usado para hacer frente al escenario que se presentan en un comentario a la respuesta de Ned ...
Asume que:
a) Este es un middleware personalizado o uno que se puede extender/envuelva con su propia clase middleware
B) su lógica puede esperar hasta process_view
en lugar de process_request
, porque en process_view
puede inspeccionar el parámetro view_func
después de que haya sido resuelto. (O puede ajustar el código a continuación para usar urlresolvers
según lo indicado por 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.
Puede haber una manera de generalizar este patrón más, pero esto cumplió mi objetivo bastante bien.
Para responder a su pregunta más general, no creo que haya nada en las bibliotecas de Django que lo ayude con esto actualmente. Sería un buen tema para la lista de correo de django-users si aún no se ha abordado allí.
Tengo una verdadera solución para este problema. Advertencia; es un poco hackeo
""" 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
Editar: eliminó la versión anterior que ejecutaba la vista dos veces.
Django urlmiddleware permite aplicar middleware solo a las vistas que se asignan a direcciones URL específicas.
Bonita aplicación, sin embargo, todavía agrega middleware global que comprueba la url solicitada contra cualquier middleware configurado específico de url: https://github.com/d0ugal/django-urlmiddleware/blob/master/urlmiddleware/middleware.py#L18 – rednaw
Lo mejor que he podido encontrar es usar if request.path_info.startswith ('...') para omitir el middleware simplemente devolviendo la solicitud. Ahora bien, podría crear middleware solo por el simple hecho de omitirlo y luego heredarlo. Tal vez podría hacer algo aún más simple y guardar esa lista en su settings.py y luego omitir todo eso. Si estoy equivocado de alguna manera, házmelo saber.
Puede usar el método process_view, que se llama antes de llamar a la función func. En process_view puede verificar si esta vista requiere esta intercepción de middleware.
creo que este es el camino más fácil para excluir una vista desde middleware
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"
- 1. django middleware conjunto usuario variable global especial
- 2. Middleware Django y HttpRequest change
- 3. Procesadores de contexto vs middleware en django
- 4. global formfield_overriding en django
- 5. accediendo al modelo desde middleware - django
- 6. Python Django Global Variables
- 7. Seguro para modificar configuraciones.SITE_ID de middleware en Django?
- 8. Tener una API POST'able y el middleware CSRF de Django
- 9. cómo insertar un texto en todo el contexto Django Django usando el middleware
- 10. ¿Es seguro el hilo de middleware de Django?
- 11. Middleware en comunicación cliente/servidor
- 12. ¿Está disponible la variable Solicitud global en Python/Django?
- 13. Definición de "variable global" en plantillas de Django
- 14. No se puede definir middleware de descarga personalizada en Scrapy
- 15. Mejor publicación/suscripción "Middleware"
- 16. ¿Debo usar un middleware de compresión GZIP o no?
- 17. fin de middleware Scrapy
- 18. debo usar en mi @csrf_protect Django vista cierre de sesión junto con el middleware
- 19. matraz: wsgi-middleware vs before_ y after_request()
- 20. Medición del tiempo de ejecución de la vista en un middleware de Django. ¿Buena idea?
- 21. Git global ignore no funciona
- 22. No contaminante global con AngularJS
- 23. Variable global "Aplicación" no reconocida
- 24. Función No Cambio Global Variable
- 25. SET GLOBAL max_allowed_packet no funciona
- 26. WSGI Middleware para autenticación OAuth
- 27. Node.js - Problema con res.redirect en middleware
- 28. Middleware Trigger Rack en rutas Rails específicas
- 29. Aplicación vs desarrollo de middleware en Android
- 30. the connect middleware for coffeescript?
Ok, pero lo que si quiero excluir middleware en lugar de añadirlos. Por ejemplo, mi archivo de configuración muestra el middleware MIDDLEWARE_CLASSES = ('A', 'B', 'C') y quiero que una vista tenga A y B pero no C. ¿Hay un decorador para eliminar el middleware?Este material personalizado de middleware es necesario en una sola aplicación de Django, por lo que no quiero tener que agregar 'decorator_from_middleware' a cada otra vista en mi aplicación. – hekevintran
'@ csrf_exempt', que hace algo similar a lo que está preguntando, funciona estableciendo un indicador en la vista que luego se verifica mediante el correspondiente middleware CSRF. No es una solución general, por supuesto, pero solo se nota. – sfridman