Search code examples
pythondjangomiddlewaredjango-csrf

Django custom middleware rendering has no csrf token


My custom middleware returns a rendered response (with RequestContext).

It seems this causes the csrf_token context var to be set to NOTPROVIDED (Djangos sentinel value for not provided), and {% csrf_token %} gives no output, as the CSRF middleware is called on process_view, which I'm assuming we never get to run in this case.

The middleware-rendered response isn't complicated, and it is a rarely used special-case, however the CSRF token is needed for changing language, as that is a POST request to Djangos built-in set_language view.

What's the best approach to solve this?


Solution

  • The reason, why you don't have the csrf token available in process_request, is that token is set in process_view of the csrf middleware, which is run after each middleware's process_request, so you need to move your code into process_view instead:

    def process_view(self, request, view_func, view_args, view_kwargs):
        if some_clause:
            return render(request, 'foo.html', {'foo': 'bar'})
    
        return view_func(request, view_args, view_kwargs)