update value of a variable inside a template - django - django

I have seen enough number of examples that allow me to declare a new variable inside a template and set its value. But what I want to do is to update the value of a particular variable inside the template.
For example I have a datetime field for an object and I want to add timezone according to the request.user from the template. So I will create a template filter like {% add_timezone object.created %} and what it will do is that it will add timezone to object.created and after that whenever I access {{object.created}} it will give me the updated value.
Can anybody tell me how this can be done. I know I need to update the context variable from the template filter. But don't know how.

You cannot modify a value in a template, but you can define 'scope' variables using the {% with %} tag:
{% with created=object.created|add_timezone %}
Date created with fixed timezone: {{ created }}
{% endwith %}
where add_timezone is a simple filter:
def add_timezone(value):
adjusted_tz = ...
return adjusted_tz
register.filter('add_timezone', add_timezone)

Related

How do I create if statement on django template?

enter image description here
If there are not projects created, projects is the name of my viewclass for my model, then I need it to create a message, but I do not know how to create the right if statement.
Standard way to implement any if statement in Django's template:
{% if my_projects %}
Do what you want if condition is ok
{% else %}
Do what you want if condition is not satisfied
{% endif %}
I assume that my_projects variable contains a list/queryset of projects if any and is passed to the view's context.

How to make context variable dynamic in django template

Is it possible to append 2 context variables together into a single context variable that is calculated at run-time?
For example: if I have {{contextA}} (which equals 1) and {{contextB}} (which equals 'building') and I wanted to add these together to get context {{1building}} How would I do this?
I have tried:
{{contextA + contextB}}
{{{{contextA}} + {{contextB}}}}
{{contextA |add: contextB}}
{{contextA contextB}}
I suppose this is not possible and this needs to be done in the view using python, but it would be ideal if I could just combine context variables in the template.
U can use {% with template tag as follows (docs here -> https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#with)
{% with newvar=contextA|add:contextB %}
{{ newvar }}
{% endwith %}
newvar will have a new value if into a forloop where contextA or contextB change it's value.
As you want to show the value of a context variable with it's name equal to newvar value, the way to accomplish it is to create a custom template tag as follows:
#register.simple_tag(takes_context=True)
def dynvarvalue(context, dynvarname):
""" Returns the value of dynvarname into the context """
return context.get(dynvarname, None)
I did a small proof of concept:
{% with 1building='1 building value' contextA='1' contextB='building' %}
{% dynvarvalue contextA|add:contextB %}
{% endwith %}
Which produces the following output, which I think is what you are asking for:
1 building value
Hope this helps.
Note: take into account that if both variables can be transformed to an integer, they will not be concatenated and will be summed as docs says (https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#add)
Note2: I think there are some security caveats to take into account doing this.

Template tag as filter value in Django

I have defined one custom tag which is working fine in templates.
Like
{% get_setting "DATE_FORMAT_UI" %}
Above statement is returning correct value in template.
Now i want to use the same in a filter like this -
{{extra_info.to_date|date: '{% get_setting "DATE_FORMAT_UI" %}' }}
But this is giving error in parsing.
I tried in different ways of using quotes for the {% get_setting "DATE_FORMAT_UI" %}
But every time bad luck.
So could any body help me in solving this. I want to pass date format in filter . That date format is saved into config file. but how to pass that value dynamically in filter.
The trick is to first assign this to a variable (here myformat), and then use that variable:
{% get_setting 'DATE_FORMAT_UI' as myformat %}
{{extra_info.to_date|date:myformat }}

Django Custom Template Tag with Context Variable Argument

I have a custom template tag which shows a calendar. I want to populate certain items on the calendar based on a dynamic value.
Here's the tag:
#register.inclusion_tag("website/_calendar.html")
def calendar_table(post):
post=int(post)
imp=IMP.objects.filter(post__pk=post)
if imp:
...do stuff
In my template, it works fine when I pass a hard coded value, such as
{% load inclusion_tags %}
{% calendar_table "6" %}
However when I try something like {% calendar_table "{{post.id}}" %} , it raises a error a ValueError for the int() attempt. How can I get around this?
You want {% calendar_table post.id %}; the extra {{ and }} are what are causing you the heartburn.
Note that, in your custom tag, you need to take the string ("post.id") that gets passed and resolve it against the context using Variable.resolve. There's more information on that in the Django docs; in particular, look here: http://docs.djangoproject.com/en/1.3/howto/custom-template-tags/#passing-template-variables-to-the-tag

Django - use template tag and 'with'?

I have a custom template tag:
def uploads_for_user(user):
uploads = Uploads.objects.filter(uploaded_by=user, problem_upload=False)
num_uploads = uploads.count()
return num_uploads
and I'd like to do something like this, so I can pluralize properly:
{% with uploads_for_user leader as upload_count %}
{{ upload_count }} upload{{ upload_count|pluralize }}
{% endwith %}
However, uploads_for_user leader doesn't work in this context, because the 'with' tag expects a single value - Django returns:
TemplateSyntaxError at /upload/
u'with' expected format is 'value as name'
Any idea how I can get round this?
You could turn it into a filter:
{% with user|uploads_for as upload_count %}
While a filter would still work, the current answer to this question would be to use assignment tags, introduced in Django 1.4.
So the solution would be very similar to your original attempt:
{% uploads_for_user leader as upload_count %}
{{ upload_count }} upload{{ upload_count|pluralize }}
Update: As per the docs assignment tags are deprecated since Django 1.9 (simple_tag can now store results in a template variable and should be used instead)
In Django 1.9 django.template.Library.assignment_tag() is depricated:
simple_tag can now store results in a template variable and should be used instead.
So, now simple tag we can use like a:
It’s possible to store the tag results in a template variable rather
than directly outputting it. This is done by using the as argument
followed by the variable name. Doing so enables you to output the
content yourself where you see fit:
{% get_current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>