{{{
#!python
from django.test import RequestFactory
from .views import MyView
from .middleware import MyMiddleware
request = RequestFactory().get('/')
view = MyMiddleware(MyView)
response = view(request)
}}}
Also, it may be needed to test views that accept arguments (e.g. captured
URL parameters), which would probably look like this:
{{{
#!python
request = RequestFactory().get('/articles/4/')
response = MyView(request, pk=4)
}}}
The problem arises when we both use test views that accept parameters and
a custom middleware. The current documentation offers examples for writing
such a middleware:
{{{
#!python
def MyMiddleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
}}}
Given the above tests, one would expect this one to work as well as
expected:
{{{
#!python
request = RequestFactory().get('/articles/4/')
view = MyMiddleware(MyView)
response = view(request, pk=4)
}}}
However this is not the case, since the `middleware` function expects only
a single positional argument and not the keyword argument `pk`, thus
raising a TypeError.
The attached files recommend a more flexible (albeit less simple) syntax
and data flow for custom middleware that would prevent inexperienced
developers from getting stuck here.
--
Ticket URL: <https://code.djangoproject.com/ticket/30101>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* Attachment "middleware_syntax_in_docs.diff" added.
Patch for documentation
Old description:
New description:
response = get_response(request)
return response
return middleware
}}}
Given the above tests, one would expect this one to work as expected too:
{{{
#!python
request = RequestFactory().get('/articles/4/')
view = MyMiddleware(MyView)
response = view(request, pk=4)
}}}
However this is not the case, since the `middleware` function expects only
a single positional argument and not the keyword argument `pk`, thus
raising a TypeError.
The attached files recommend a more flexible (albeit less simple) syntax
and data flow for custom middleware that would prevent inexperienced
developers from getting stuck here.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/30101#comment:1>
* type: Uncategorized => Cleanup/optimization
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/30101#comment:2>
Comment (by Nasir Hussain):
Replying to [comment:1 Theodore Diamantidis]:
Should I create a PR with the patch in the documentation you provided?
I don't know what's the next steps if someone uploads a patch file too.
--
Ticket URL: <https://code.djangoproject.com/ticket/30101#comment:3>
* status: new => closed
* resolution: => invalid
Comment:
This usage isn't correct:
{{{
view = MyMiddleware(MyView)
}}}
It treats views and middlewares as if they were equivalent, which they are
not.
Django's `BaseHandler` provides a `_get_response()` method that uses the
`URLConf ` and `URLResolver` to determine the callback (i.e. view
function) and parameters to pass to the view.
([https://github.com/django/django/blob/d02b2aa11e5b6c351a9a2c0673c23569889f90d6/django/core/handlers/base.py#L100-L101
django/core/handlers/base.py].)
It's this `_get_response()` that sits at the center of the ''Middleware
Onion™''. You can't just pass in a view.
To simulate the full dispatch you'd need to do something like this, as a
minimum:
{{{
request = RequestFactory().get('/articles/4/')
def _get_response(request):
return MyView(request, pk=4)
middleware_chain = MyMiddleware(_get_response)
}}}
(Lots of ways we might make that better...)
I've thought about adding something on this to the
[https://docs.djangoproject.com/en/2.1/topics/http/middleware/ middleware
usage guide] but, by the time you're jumping through these hoops, I think
the best advice is to **use the provided test client** and let Django
handle the mapping between your middleware and views.
--
Ticket URL: <https://code.djangoproject.com/ticket/30101#comment:4>