Hi, Amit!
Check this utils function:
http://code.djangoproject.com/browser/django/trunk/django/utils/decorators.py#L9
There are two cases, each with drawbacks:
1. Whatever system is available to provide additional processing is by
default applied only to a single specific view (e.g., a decorator).
The drawback is that you will inevitably want an easy way to say
"apply this everywhere" instead of manually applying the decorator to
every view.
2. Whatever system is available to provide additional processing is by
default applied to every view (e.g., a middleware class). The drawback
is that you will inevitably want an easy way to say "apply this only
to this specific view" instead of writing and maintaining a separate
copy of the code.
Both of these solutions' drawbacks can be solved by helper code: a
utility which transforms a decorator into a middleware class could be
provided, or a utility which transforms a middleware class into a
decorator could be provided.
Django has chosen option 2, and provided the helper method to go from
middleware -> decorator as needed.
This does have some advantages:
1. It's easier to lay out a readable API that determines when a
particular piece of code gets executed; figuring out whether a
decorator turns into a 'process_request' or a 'process_response', for
example, would be tricky, but plucking out a middleware class' methods
and applying them at the correct points in a decorator is easy.
2. Providing a dedicated global middleware API opens up some hooks
that wouldn't otherwise be available; for example, when going from a
middleware to a decorator you can still have a 'process_request'
phase, but it doesn't occur at the same time and you can't do some of
the useful tricks that a real middleware can do -- for example, you
can't tweak request.urlconf to change URL resolution, because by the
time a decorated view comes into play the URL resolution phase is
over.
--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."
Well. I should say you can't do them as easily. You could, I suppose,
write a decorator which imports the URL resolution machinery and does
a fresh match based on new URL patterns, then calls the view that
comes out of that, but it'd be awfully tedious compared to the way it
works in middleware.
There are two cases, each with drawbacks:
On Sun, Apr 13, 2008 at 6:05 AM, Amit Upadhyay <upad...@gmail.com> wrote:
> I was wondering about the reason that middleware classes were used instead
> of decorators to implement middleware functionality.
1. Whatever system is available to provide additional processing is by
default applied only to a single specific view (e.g., a decorator).
The drawback is that you will inevitably want an easy way to say
"apply this everywhere" instead of manually applying the decorator to
every view.
Call me crazy, but I'm not seeing anything here that can't be done in
the process_view() stage of middleware. It receives the incoming
request, the view that's about to be executed (so you can get its
module path), as well as the arguments that will be applied to it.
The code you specified could actually be run inside there, executing
the view directly if you like, then returning the response directly
from process_view(), bypassing the rest of the middleware phase. It
doesn't sound like a pleasant situation to me, but neither does what
you're trying to accomplish.
I really think you're looking for a middleware that implements
process_view(). Look into it,[1] if you haven't already.
-Gul
[1] http://www.djangoproject.com/documentation/middleware/#process-view