Accessing session value in django template - django

I am setting
request.session['total_items'] = 3
in a views.py file of a django app
in template
i got to know that you can access it as {{request.session.total_items}}
Everything is fine and i'm able to get the value.
However,my question is that why it is not {{request.session['total_items']}} instead, since request.session is a dictionary like object.
For {{request.session['total_items']}}, its giving an error as following:
Could not parse the remainder: '['total_items']' from 'request.session['total_items']'
Any help would be appreciated ...

Do not confuse Django template language with Python Syntax. Django template language its a language on its own and have its own way of performing things. As doc suggests:
The goal is not to invent a programming language. The goal is to offer
just enough programming-esque functionality, such as branching and
looping, that is essential for making presentation-related decisions.

When you have enabled the django.core.context_processors.request it will enable the access to the values of a dictionary-like objects with the . notation.
This will convert any Python object into something that the Django template language will understand as it is its own language.
This also applies for the following:
Attribute lookups (eg. myobject.age)
Method calls (eg. myobject.age())
List indices (eg mylist.1)
The thing that is working it behind the scenes is the Context object.
You can read more on how it works here and here
And you can compare the Python controlstructure if to Django's template language.
if object:
myobject.dostuff()
to
{% if object %}
{{ myobject.dostuff }}
{% endif %}
If you want a closer match to Python you should check out
Jinja2
PyHAML

Related

Does Django cache custom tags and filters?

I have a considerable number of custom template tags that perform a variety of functions, including:
simple string transformation
display of complex ui elements
timestamp manipulation and formatting
handling and display of user avatars
etc...
All of these functions reside in a single file: app/templatetags/custom_tags.py. When I want to use one of these tags in a template, I import all of them using {% load custom_tags %}.
However, only a small subset of the available tags are actually used in any given template. In other words, all these functions are being 'loaded' into the template, yet only a few of them are called in a specific web request.
Is this inefficient, in terms of performance? Should I be loading code more conservatively -- i.e., splitting up my custom tags into separate files and only loading the subset that I need?
Or does this not matter, because all tags are loaded in memory -- i.e., subsequent calls to {% load custom_tags %} elsewhere in the application won't result in any additional overhead?
I apologize if there are incorrect assumptions or premises in this question. I'd love to have a better understanding of the implications of importing python code in general, or in a Django environment specifically.
For Django <= 1.8:
The load tag is defined here and actually does the loading here and here. Both places call to get_library, defined here. According to the docstrings there, yes, it caches template tag/filter libraries within the same process in the dictionary initalized here.
For Django 1.9:
The modules for template tags are now being loaded even earlier, when the parser is instantiated, and the libraries are being stored directly on the parser. Load tags call out to find_library here and here, which just gets the already-loaded tag directly from the parser.
Aside from the actual loading activity
As #spectras points out below, regardless of the Django version, the tag's loading behavior is, strictly speaking, a side effect, and the tag returns (<=1.8/1.9) a no-op node(<=1.8/1.9), which renders no content--so there's not really a performance consideration as far as that goes.

Can you use two HTML templates such as Handlebars and Jinja

I'm trying to write an app in javascript with the ember.js library which relies heavily on the Handlebars templating system. However, I'm using FLASK which also uses the jinja templating system.
Is it possible to use both template renderers at the same time? Or do I need to use one over another. Anyone with experience using both flask and ember.js know which one would potentially be easier to replace with the other?(Maybe handlebars is much easier to replace Jinja with or vice versa).
Note that these two template engines are in different places. Jinja2 will run on the server side, Handlebars will run on the client side. You could potentially use both without interference if you needed to.
But with that said, there is really no need to use server-side templates if you have a rich client framework like ember.js. In your situation the Flask server will likely have routes that serve data via ajax requests back to the ember.js client, so the client is really the best place for template rendering to happen.
You can mark sections of code as {% raw %} to tell jinja2 to ignore it. Wrap your handlebars.js template in raw tags like so:
{% raw %}
<script id="foo-template" type="text/x-handlebars-template">
<p>{{foo}} - {{bar}}</p>
</script>
{% endraw %}
As #Miguel said, you don't really need Jinja2 if your using ember.js, I figured out if you don't want to render those templates, simply return flask.send_file('your html file here') instead returning flask.render_template('your html file here'). See the docs for more details.
While I fundamentally agree with both #Miguel and #Ali, several companies I have worked with mix the RESTful model for APIs with server-generated HTML. [NOTE: This shouldn't be the case when using Ember, but I'm working with Flask / Jinja2 and Backbone in my current client's code base.]
I actually found a solution using Pybars, based on some reading from Khan Academy's style guide:
#app.template_filter("handlebars")
def handlebars_filter(context, filepath):
source = open( filepath, "r").read().decode('utf-8')
template = pybars.Compiler().compile( source )
return Markup( u"".join( template( context )))

Setup Jinja2 in Django Project

Newbie question, yet I cannot find a sufficient step-by-step instruction on Jinja2 official website or by googling.
My current Django project is halfway done, and I cannot stand not able to use queryset filter in Django template anymore. So decide to switch to Jinja2.
What I have done: pip install jinja2 to the virtualenv. Then I tried to use Jinja syntax in my template files, which fails.. apparently and sadly
What else do I need to do to make Jinja2 work?
I just want to recommend two alternatives I find very useful.
Jinja template tag
One is the jinja template tag which lets you use jinja within django templates as
{% jinja %}{{ this_is_jinja(True)}}{% endjinja %}
Very useful when you can't / don't want to break the rest of your existing templates.
http://www.mellowmorning.com/2010/08/24/mixing-django-with-jinja2-without-losing-template-debugging/
Conditional template engine
The other is conditional loading of template engines based on filename (note I wrote this since I use both template languages):
https://github.com/yuchant/django-jinja2
You'll need to switch to using a rendering method that uses Jinja2 templates instead of Django templates - coffin has a helper you can use named render_to_response that should work.

django admin colon syntax in template tags and in reverse function

While learning with Django by Example, I have found something I don't yet know and haven't found any reference for it. I'm sure it is well documented somewhere, but I haven't found out how to search for it. Also, I apologize if I'm reasking an already answered question, I haven't found it here either.
What I would like to understand is the "admin: ..." syntax, which I met in several contexts:
In a template .html file:
Add Todo items
In a view function:
return HttpResponseRedirect(reverse("admin:todo_item_changelist"))
I have gone through the djangoproject tutorial and the first 8 chapters of djangobook, and I didn't meet it there. I know, though, that in a reverse function a view function may be passed, and that {% %} template tags 'do something', but I have only seen dotted syntax used for these cases, so far. May it be that for referencing admin features, instead of the dotted syntax, we use this colon?
I would really appreciate some brief explanation on what it does.
It's URL namespace. Admin docs:
https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#admin-reverse-urls, general URL namespace docs: https://docs.djangoproject.com/en/2.2/topics/http/urls/#url-namespaces.
from django docs:
If you'd like to retrieve a namespaced URL, specify the fully qualified name:
{% url 'myapp:view-name' %}
This will follow the normal namespaced URL resolution strategy, including using any hints >provided by the context as to the current application.

How to pass an argument to a method on a template variable in Django?

I am using the lxml library to define a variable (category) in a view. lxml provides a method .get to retrieve custom attributes. I'd like to use it in the template like so:
{{ category.get("foo") }}
I know that when using template variables it is unnecessary to use parenthesis, but I get the following error:
{{ category.get "foo" }}
Could not parse the remainder: ' "foo"' from 'category.get "foo"'
I'm assuming that there is something wrong with my syntax but google has been no help. The django docs say that methods are looked up by using a .
You can't pass an argument to a callable attribute like this. Either pull the value in the view, or write a custom template tag to do it.
I agree with the philosophy of separating logic from design, but there's an exception. I am currently writing a get_image(height=xxx, width=xxx) method for a model. Clearly, it should be up to the template designer to decide the size of the image as the last stage. Though I suppose the correct thing to do is write a custom tag, but why restrict?
Here I wrote a hack to call a function and pass the arguments
http://www.sprklab.com/notes/13-passing-arguments-to-functions-in-django-template/