--
Ticket URL: <https://code.djangoproject.com/ticket/26626>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => assigned
* owner: nobody => carljm
--
Ticket URL: <https://code.djangoproject.com/ticket/26626#comment:1>
Comment (by Tim Graham):
Absent a compelling use case for this update and due to some limitations
in how effectively `decorator_from_middleware` can make the
transformation, we decided not to move forward with this. A query about it
has been raised
[https://www.reddit.com/r/django/comments/5s052v/decorator_from_middleware_doesnt_work_with_the/
on Reddit]. I've asked if that poster can give a use case here.
--
Ticket URL: <https://code.djangoproject.com/ticket/26626#comment:2>
Comment (by Andreas Pelme):
A use case for this is tests. I have a middleware that handles temporary
unavailability by showing a loading page/returning HTTP 503 for certain
exceptions.
This particular middleware uses custom logic in `__call__` and
`process_exception`. `decorator_from_middleware` makes it easy to test
this middleware:
{{{
@override_settings(MAINTENANCE_MODE=True)
def test_maintenance_mode(self):
@decorator_from_middleware(TemporaryUnavailable)
def view():
raise AssertionError("don't call")
response = view(RequestFactory().get('/')
assert response.status_code == 503
}}}
Of course, I could craft my own get_response, initiate the middleware and
call `__call__` or `process_exception` directly but that is ugly and easy
to get some details wrong, especially when the test involves exceptions.
--
Ticket URL: <https://code.djangoproject.com/ticket/26626#comment:3>
Comment (by Andreas Pelme):
Another use case:
We have a custom authentication mechanism that is not tied to
contrib.admin for our main site.
However, we use contrib.auth for administrative accounts. To make it very
clear which views needs a real user, we have disabled the auth middleware
globally and use a custom admin site that selectively enables auth:
{{{
from django.contrib import admin
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.utils.decorators import decorator_from_middleware
auth_decorator = decorator_from_middleware(AuthenticationMiddleware)
class AdminSite(admin.AdminSite):
def admin_view(self, view, cacheable=False):
super_wrapper = super().admin_view(view, cacheable=cacheable)
return auth_decorator(super_wrapper)
}}}
(This use case is fine and works fine in Django 1.10 since Django's built
in `AuthenticationMiddleware` is both old and new-style, but I just wanted
to highlight that `decorator_from_middleware` is useful in different
contexts)
--
Ticket URL: <https://code.djangoproject.com/ticket/26626#comment:4>
Comment (by David Svenson):
The following function takes a new-style middleware class and makes a view
decorator out of it. It's used in code that me and @pelme are working on,
though not as a decorator.
{{{
def decorator_from_middleware_new(new_middleware_cls):
def view_decorator(view_function):
def view(request, *args, **kwargs):
def get_response(request_inner):
assert request is request_inner
try:
return view_function(request, *args, **kwargs)
except Exception as e:
new_middleware.process_exception(request, e)
return HttpResponseServerError()
new_middleware = new_middleware_cls(get_response)
return new_middleware(request)
return view
return view_decorator
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26626#comment:5>
* owner: Carl Meyer => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/26626#comment:6>