Django using locals() [duplicate] Django using locals() [duplicate] django django

Django using locals() [duplicate]


Using locals() in that tutorial is just for convenience, since all the data he needs to pass to the template is stored in local variables. locals() returns a dictionary holding the local variables names (as keys) and the current values (as values).

You need to use an explicit context_dictionary, instead of passing locals(), if you must build your data and you don't have such data in separate variables.

both locals() and context_dictionary are dictionaries, and that's the only requirement: a dictionary-like object (i.e. an object supporting __getitem__(key) and get(key, default=None) methods). How you get the dictionary, is up to you. There's no practice about that, but alternatives are:

  • Return a RequestContext(), which is a dict-like object, if you use CONTEXT_PROCESSORS.
  • Return locals() if you have the data in your local variables.
  • Return a hand-made dictionary with your data otherwise.

EDIT - Examples:

Example on building the dictionary on your own:

def my_view(request):    return render_to_response('hello.html', {        'full_name': u"%s %s" % (request.user.first_name, request.user.last_name),        'username': request.user.username    })

Example on building the dictionary from locals():

def my_view(request):    full_name = u"%s %s" % (request.user.first_name, request.user.last_name)    username = request.user.username    return render_to_response('hello.html', locals())

Assume hello.html is - in either case:

<html>    <body>        You are {{ full_name }} ({{ username }})    </body></html>

You'll get the expected result.


if your view looks something like this:

def myview(request):    thing = 1    name = 'fred'    stuff = ['a', 'b', 'c']

and in your template you want to do:

{{ thing }} of {{ name }} has {% for x in stuff %}{{ x }}{% endfor %}

then in the view you could:

    return render(request, 'template.html', locals())

This is because locals() returns a dict of all the locally defined variables in the current scope. So it's kind of a sneaky shortcut.

Be careful though, since you are likely to expose more values than you intend to... generally we'd prefer the "Explicit is better than implicit" approach from the Zen of Python i.e. define a dict containing only what you want to pass through to the template.

def myview(request):    context = {       'thing': 1,       'name': 'fred',    }    # do more code...    context['stuff'] = ['a', 'b', 'c']    return render(request, 'template.html', context)


What you mean by context dictionary is the named arguments? If yes, they're different, locals shows you all the locals variables, kwargs dictionary instead shows only the named arguments.

def test(**kwargs):   c = 'abc'   print kwargs   print locals()test(a=10, b=20)

The first print shows: {'a': 10, 'b': 20} while the second one shows: {'c': 'abc', 'kwargs': {'a': 10, 'b': 20}}