简体   繁体   中英

Django context processor - 'str' object is not callable

I'm trying to build dynamic sidebar with context processor. I take distinct values for sidebar from database table.

Here's my context processor:

from clients.models import client
def sidebar(request):
        return {'clientlist': client.objects.order_by('name').distinct('name')}

In views.py I have following code:

from django.shortcuts import render
from django.template import loader, RequestContext
from clients.models import client
def index(request):
        allclientlist = client.objects.all()
        return render (request, 'clients/index.html', {'allclientlist': allclientlist}, context_instance=RequestContext(request, processors=['sidebar']))

allclientlist used to generate a table with all clients and their data. Next I'm trying to build dynamic sidebar with context processor and get following traceback

Traceback:
File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/root/projects/webapp/clients/views.py" in index
  7.    return render (request, 'clients/index.html', {'allclientlist': allclientlist}, context_instance=RequestContext(request, processors=['sidebar']))
File "/usr/local/lib/python2.7/site-packages/django/template/context.py" in __init__
  179.             self.update(processor(request))

Exception Type: TypeError at /clients/
Exception Value: 'str' object is not callable

It worked when it was like:

def index(request):
       allclientlist = client.objects.all()
       clientlist = client.objects.order_by('name').distinct('name')
       return render(request, 'clients/index.html', {'allclientlist': allclientlist, 'clientlist': clientlist})

But to make this menu available in all views, I needed to have clientlist declaration in all views. I wanted to avoid this and stuck. Please, help me to find this error.

If you want clientlist included in all views, then add client.models.sidebar to your TEMPLATE_CONTEXT_PROCESSORS setting, and remove the context_instance argument from the render call in your view - when you use the render shortcut, the template is automatically rendered with a request context.

def index(request):
    allclientlist = Client.objects.all()
    return render(request, 'clients/index.html', {'allclientlist': allclientlist})

As an aside, the Django convention would be to move the sidebar context processor into a client.context_processors module, and to capitalise your model as Client .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM