The django books gives the local trick in order to avoid to type a long list of parameters as context dictionnary
http://www.djangobook.com/en/2.0/chapter04/
Example:
def current_datetime(request): dt_now = datetime.datetime.now() return render_to_response('current.html', {'dt_now': dt_now})
becomes:
def current_datetime(request): dt_now = datetime.datetime.now() return render_to_response('current.html', locals())
It recommends this to lazy programmers but points out some overhead which may have an impact on performance.
I would like to know if some of you are using the locals trick on real applications. Do you recommend it or is it a bad practice?
locals() is a Python built-in function that according to the official Python documentation: Updates and returns a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.
{% %} is basically used when you have an expression and are called tags while {{ }} is used to simply access the variable.
To configure the Django template system, go to the settings.py file and update the DIRS to the path of the templates folder. Generally, the templates folder is created and kept in the sample directory where manage.py lives. This templates folder contains all the templates you will create in different Django Apps.
To create and use for loop in Django, we generally use the “for” template tag. This tag helps to loop over the items in the given array, and the item is made available in the context variable.
I don't like repetition -- I think "DRY", "Don't Repeat Yourself", is a key programming principle. As a consequence, I have indeed used locals()
in similar situations. Django template rendering is far from the only situation of this kind: the general case is "a function or operator which accepts a dict, but doesn't mind if the dict contains extra entries". (For example, ordinary string formatting in Python is another such case).
However, there's a countervailing principle: programs should be understandable in as localized a way as feasible -- that helps maintenance and refactoring (as it obviates the need to study other files to check what refactorings are acceptable). This suggests, for the locals()
case, that it's OK if the template (or string format, etc) is a local literal (a rare case where only few variables are probably being used and thus locals()
is not a huge win!-), but problematic in the normal case where the template lives in a different file.
So, using locals()
, in most cases, seriously hampers refactoring. In almost every situation in Python, local variables and their names can freely be changed as part of a local refactoring, since they have no "externally visible" effect... but using locals()
breaks that -- suddenly you can't safely rename a variable to a different name offering better clarity, refactor code flow in a manner that removes the need for a variable, etc, etc, without each and every time studying a separate template file to check if the old name might not be needed (and possibly editing the template file, which can be non-trivial, for example if it's maintained in several different natural languages for i18n/L10n purposes).
As a consequence, in addition to the secondary issue of performance, there is strong pressure against using locals()
in "serious", "production" code -- code that does need long term maintenance and therefore easy refactoring and locality. So, when I'm "programming as best I know how", rather than "cutting corners", I'm aware I had better avoid locals()
.
The values that you want to have in the context in which the template is rendered are not necessarily "naturally" available as local bare-names, after all; maybe some or many of them are results of computations, items from lists or dictionaries, and the like. In this case, the temptation to "cut corners" with locals()
is easier to avoid if you just accumulate those values into a suitable dictionary rather than assigning them local bare-names.
It's not the easiest tradeoff, because two good principles (avoiding repetition, and having good locality) are inevitably clashing -- therefore, good question! And not one entirely susceptible to sharp black or white answers, which is why I've tried to expand on both sides. In the end, I think it's one of those "style" aspects where a programming team might be well advised to adopt a team-uniform style guideline and stick to it -- at least it removes the need to make a decision over and over every time the issue arises, and produces a more homogeneous (and thereby maintainable) code base. [[I have to confess that this specific point has never been explicitly addressed in the style guidelines of teams I've been in, though, although many others have!-)]]
I often thought of doing the following, but I am not sure if it is really helpful.
class MyStruct(object): pass def my_view(request, id): c = MyStruct() c.customer = .. c.invoice = .. c.date = .. return render_to_response('xxx,html',c.__dict__)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With