I'm trying to add a context processor custom_proc to pass variables to the template context. Code:

def custom_proc(request): """A context processor that provides 'app', 'user' and 'ip_address'.""" return { 'app': 'MyApp', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'] } def index(request): template = loader.get_template('core/index-main.html') context = RequestContext( request, { 'message': 'My message' }, processors=[custom_proc] ) return HttpResponse(template.render(context)) 

At the same time, variables from custom_proc are not included in the template.

If instead of loading the template, I will point it directly to the line:

 template = Template('{{ app }} {{ user }} {{ ip_address }}') 

then the context processor executes and the variables fall into the template.

Searching by code showed that in order to bind variables you need to pass a query to the second parameter in render, but when you try to do:

 return HttpResponse(template.render(context, request)) 

The application crashes with the error:

 Internal Server Error: / Traceback (most recent call last): File "E:\var\www\RQ30\venv\lib\site-packages\django\core\handlers\exception.py", line 39, in inner response = get_response(request) File "E:\var\www\RQ30\venv\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response response = self.process_exception_by_middleware(e, request) File "E:\var\www\RQ30\venv\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "E:\var\www\RQ30\aisog\aisog\core\views.py", line 27, in index return HttpResponse(template.render(context, request=request)) File "E:\var\www\RQ30\venv\lib\site-packages\django\template\backends\django.py", line 64, in render context = make_context(context, request, autoescape=self.backend.engine.autoescape) File "E:\var\www\RQ30\venv\lib\site-packages\django\template\context.py", line 267, in make_context context.push(original_context) File "E:\var\www\RQ30\venv\lib\site-packages\django\template\context.py", line 59, in push return ContextDict(self, *dicts, **kwargs) File "E:\var\www\RQ30\venv\lib\site-packages\django\template\context.py", line 18, in __init__ super(ContextDict, self).__init__(*args, **kwargs) TypeError: dict expected at most 1 arguments, got 3 

Question: what am I doing wrong?

    2 answers 2

    Try creating a new context_processors.py file context_processors.py this content:

     def custom_proc(request): """A context processor that provides 'app', 'user' and 'ip_address'.""" return { 'app': 'MyApp', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'] } 

    In TEMPLATES in the file settings.py add your context_processors.py file

     TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ ..., 'YOU_PROJECT.context_processors.custom_proc', ], }, }, ] 

    And rewrite the index

     from django.shortcuts import render def index(request): return HttpResponse(render(request, 'index.html', context={'message': 'My ip'})) 
    • But will it be a global processor? Who will add data to all forms? - Dmitry Kozlov
    • Then in index add the context variable in the form of a dictionary, without using the custom_proc function - s.gaynetdinov

    Why not use Class Based Views?

     from django.views.generic import TemplateView class CustomProcTemplateView(TemplateView): def get_context(self): request = self.request context = super(CustomProcTemplateView, self).get_context() context.update({ 'app': 'MyApp', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'] }) return context class IndexView(CustomProcTemplateView): template_name = 'core/index-main.html' # urls.py urlpatterns = [ url(r'', CustomProcTemplateView.as_view()), ... ] 

    Classes are much more convenient, you can inherit, write mixins, check rights. And with the FBV, you have to write it into a view every time.