Once I saw strange blog entry saying that this code
def list_items(request):
items = Item.objects.all()
return render(request, 'items.html', locals())
is better than this
def list_items(request):
data = {}
items = Item.objects.all()
data['items'] = items
return render(request, 'items.html', data)
because “you end up both having a consistent naming policy and you don’t have to waste lines doing data dict assignments”.
This is disputable statement. Comparison is not quite fair: such “named” context dict
s are rare. In most cases it is either dictionary class or dictionary literal passed directly to rendering function as an argument without any name assignments: render(request, 'tmpl.html', {'some': 'data'})
. Plus, consistent naming policy and “wasted lines” have nothing to do with locals()
. Actually, such abuse of this built-in function may lead to bugs (including privacy ones). These bugs potentially lead to serious lawsuits against owner (and/or developer) of application.
locals()
, according to documentation, “updates and returns a dictionary representing the current local symbol table”. With CPython, PyPy, and Jython it returns the same dictionary (didn’t check other implementations, though). So, in first snippet, locals()
will return dict
with two pairs, with two keys: request
, and items
. How that may lead to disaster?
When you’re passing things explicitly (explicit is better than implicit), you can quickly grasp what context template will have (though Django “helps” here via context processors) and what happens on lines between def
and return
. Sure, setting template context variables is more verbose, but it prevents context pollution and accidental disclosure of confidential data:
def show_item(request, pk):
item = get_object_or_404(Item, pk=pk)
secret_data = get_secret_data(item)
item.smth = calculate_smth(secret_data)
# ...do something else with secret_data
return render(request, 'items/show_item.html', {'item': item})
It this case locals()
will return dict
with secret_data
. Explicit declaration prevents, at some extent, template writer to unintentionally leave sensitive data output (“debugging”) template code in codebase (or at least it prevents output of such data). Also, in most projects, templates are frontend developer’s expertise. That person may be unfamiliar with Python, thus explicit “list” of objects available in templates is a good thing, as it is much easier to read.
This blog is about things I encounter while doing web and non-web software development.