Django: adding context to response using decorator

Given the following scenario:

from django.shortcuts import render def decorator(view): def wrapper(request, *args, **kwargs): context = {'foo': 'bar'} # Logic ... return view(request, *args, **kwargs) return wrapper @decorator def index(request): return render(request, 'index.html') 

I would like the decorator to add a context dictionary to the view, so that the styled function that returns is as follows:

 return render(request, 'index.html', context) 

Is it possible?

+6
source share
2 answers

After a bunch of searches, I figured out how to do it in such a way that there wasn’t too much power in the original function, keeping things DRY. The key is the Django TemplateResponse object, which discards the display of the template until a response is sent to the user, opening up possibilities for processing by decorators (and middleware, FWIW).

Here's what it looks like now:

 from django.template.response import TemplateResponse def decorator(view): def wrapper(request, *args, **kwargs): r = view(request, *args, **kwargs) r.context_data = {'foo': 'bar'} return r.render() return wrapper @decorator def index(request): return TemplateResponse(request, 'index.html') 
+4
source

This is not possible, since your function is currently written for you, but for the same behavior you can do something like the following:

 from django.shortcuts import render def decorator(view): def wrapper(request, *args, **kwargs): context = {'foo': 'bar'} args = args + (context,) return view(request, *args, **kwargs) return wrapper @decorator def index(request, *args): return render(request, 'index.html', *args) 

This will force the decorator to add your context dictionary to the end of the positional arguments, which are passed to index() , which are then passed to render() .

+3
source

Source: https://habr.com/ru/post/947586/


All Articles