Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django using locals() [duplicate]

Tags:

python

django

I am beginner in web development with Django. I have noticed that the locals() function is used instead of the context dictionary that I am used to see.

From what I see on the internet locals() is pretty useful, so are there any special cases where this is not true and its better to use the context_dictionary?

like image 629
Martin Spasov Avatar asked Jul 31 '14 15:07

Martin Spasov


2 Answers

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)
like image 44
Anentropic Avatar answered Sep 21 '22 03:09

Anentropic


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.

like image 63
Luis Masuelli Avatar answered Sep 22 '22 03:09

Luis Masuelli