How to convert integer value to string in Django templates - django

I want to convert something like that id,name to something like that "id","name" in django template.
I looked at django template built in tags but none of them works.
Does anyone have an idea to achieve it?

you can do this by writing a custom Template Tag:
besides your templates folder add a directory named templatetags.
create convert_tags.py in your templatetags directory:
# convert_tags.py
from django import template
register = template.Library()
#register.filter()
def add_quotes(value: str):
""" Add double quotes to a string value """
return f'"{value}"'
In your templates load convert_tags:
<!-- template.html -->
{% load convert_tags %}
{{ your_str|add_quotes }}

You can simply
"{{ id }}", "{{ name }}"
Or you can define a custom template tag to do this dynamically
from django import template
register = template.Library()
#register.simple_tag
def quote(str):
return f'"{str}"'
And in your template
{{ id | quote }}, {{ name | quote }}

Thanks for everyone,
I solved it by creating a custom template tag
Here's the code :
from django import template
register = template.Library()
def add_quote(var):
return '"{0}"'.format(var)
#register.filter()
def add_quotes(value):
""" Add double quotes to a string value """
excluded_fields = value.split(',')
return ",".join(add_quote(i) for i in excluded_fields)

Related

How to use special variables in django template?

I want to use dp/L and dp/L-fit variable of dictionary in html table rows in django template.
Example:
[{'PIR': 3133510.2695076177, 'PVR': 13810.315856115429, 'curve': [{'v': 0.1633026324384349, 'dP/L': 85905.56295072743, 'dP/L-fit': 85818.9286758735, 'error': -0.001008482709130518}]}]
When I use {{ dP/L }}, it gives me an error.
As I know you just can't use special characters in template variable.
So if you want to do use a special characters key in template create a custom templatetags:
create template tag file for app like templatetags/dict_tags.py
from django import template
register = template.Library()
#register.filter
def get_value(d, key):
return d.get(key)
and in template
{% load dict_tags %}
{{ dict_variable | get_value:'dP/L' }}

Using template tag in ModelAdmin.readonly_fields method

I use this pattern:
class PersonAdmin(admin.ModelAdmin):
readonly_fields = ('address_report',)
def address_report(self, instance):
return format_html(...)
Source: docs about readonly_fields
Now I would like to use a custom templatetag in the Python method address_report().
What is the best way to call it?
I tried to called my templatetag directly, but this just returns a dictionary, not html.
I think you'll have to create a template from string. That way you can use any template tags or variables you want.
Example:
from django.template import Template, Context
def address_report(...):
# create template
t = Template("""
{% load custom_tag_module %}
<p>
Hello, {{ name }}! <br>
{% custom_tag %}
</p>
""")
# create context
c = Context({'name': 'World'})
# render template, mark safe and return
return mark_safe(t.render(c))

Custom render RichTextBlock to remove <div class="rich-text">

I'm sure the answer is right there and I'm not seeing it. How can I render a RichTextBlock to remove the wrapping <div class="rich-text">?
{% include_block block %} and {{ block.value }} both give the wrapping div.
Unfortunately this is hard-coded and can't currently be overridden - see https://github.com/wagtail/wagtail/issues/1214.
I solved this by creating a custom template tag
In your project create a file in your templatetags directory (e.g. templatetags/wagtailcustom_tags.py) with content along the following.
from django import template
from django.utils.safestring import mark_safe
from wagtail.core.rich_text import RichText, expand_db_html
register = template.Library()
#register.filter
def richtext_withclasses(value, classes):
if isinstance(value, RichText):
html = expand_db_html(value.source)
elif isinstance(value, str):
html = expand_db_html(value)
elif value is None:
html = ""
else:
raise TypeError(
"'richtext_withclasses' template filter received an invalid value; expected string, got {}.".format(
type(value)
)
)
return mark_safe('<div class="' + classes + '">' + html + "</div>")
Then in your templates load the template tag
{% load wagtailcustom_tags %}
and render richtext fields with the custom classes (or no classes at all)
{{ myfield | richtext_withclasses:"my custom class" }}

Django template: how to show dict whose key has a dot in it? d['key.name']

I have a dictionary like this:
dict_name['keyname.with.manydots']
Problem: I can't do a
{{ dict_name.keyname.with.manydots }}
I know it's not possible to do this with Django's templating.. but what is the best work-around you've found? Thanks!
You could write a custom template filter:
from django import template
register = template.Library()
#register.filter
def get_key(value, arg):
return value.get(arg, None)
And in your template
{{ my_dict|get_key:"dotted.key.value" }}
One possible solution, is to create a template tag with the dictionary as the variable and the key as the argument. Remember to emulate Django's default behavior for attribute lookups that fail, this should not throw an error, so return an empty string.
{{ dict_name|get_value:"keyname.with.manydots" }}
#register.filter
def get_value(dict_name, key_name):
return dict_name.get(key_name, '')

Check if a template exists within a Django template

Is there an out-of-the-box way of checking if a template exists before including it in a Django template? Alternatives are welcome too but some of them would not work due to the particular circumstances.
For example, here's an answer to a slightly different question. This is not what I'm looking for:
How to check if a template exists in Django?
Assuming include doesn't blow up if you pass it a bad template reference, that's probably the best way to go. Your other alternative would be to create a template tag that essentially does the checks in the link you mentioned.
Very basic implementation:
from django import template
register = template.Library()
#register.simple_tag
def template_exists(template_name):
try:
django.template.loader.get_template(template_name)
return "Template exists"
except template.TemplateDoesNotExist:
return "Template doesn't exist"
In your template:
{% template_exists 'someapp/sometemplate.html' %}
That tag isn't really all that useful, so you'd probably want to create one that actually adds a variable to the context, which you could then check in an if statement or what not.
I encountered this trying to display a template only if it exists, and wound up with the following template tag solution:
Include a template only if it exists
Put the following into yourapp/templatetags/include_maybe.py
from django import template
from django.template.loader_tags import do_include
from django.template.defaulttags import CommentNode
register = template.Library()
#register.tag('include_maybe')
def do_include_maybe(parser, token):
"Source: http://stackoverflow.com/a/18951166/15690"
bits = token.split_contents()
if len(bits) < 2:
raise template.TemplateSyntaxError(
"%r tag takes at least one argument: "
"the name of the template to be included." % bits[0])
try:
silent_node = do_include(parser, token)
except template.TemplateDoesNotExist:
# Django < 1.7
return CommentNode()
_orig_render = silent_node.render
def wrapped_render(*args, **kwargs):
try:
return _orig_render(*args, **kwargs)
except template.TemplateDoesNotExist:
return CommentNode()
silent_node.render = wrapped_render
return silent_node
Access it from your templates by adding {% load include_maybe %} at the top of your template, and using {% include_maybe "my_template_name.html" %} in code.
This approach has the nice side effect of piggy-backing the existing template include tag, so you can pass in context variables in the same way that you can with a plain {% include %}.
Switch based on whether a template exists
However, I wanted some additional formatting on the embedding site if the template existed. Rather than writing an {% if_template_exists %} tag, I wrote a filter that lets you work with the existing {% if %} tag.
To this end, put the following into yourapp/templatetags/include_maybe.py (or something else)
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter
#stringfilter
def template_exists(value):
try:
template.loader.get_template(value)
return True
except template.TemplateDoesNotExist:
return False
And then, from your template, you can do something like:
{% load include_maybe %}
{% if "my_template_name"|template_exists %}
<div>
<h1>Notice!</h1>
<div class="included">
{% include_maybe "my_template_name" %}
</div>
</div>
{% endif %}
The advantage of using a custom filter over using a custom tag is that you can do things like:
{% if "my_template_name"|template_exists and user.is_authenticated %}...{% endif %}
instead of using multiple {% if %} tags.
Note that you still have to use include_maybe.
I needed to conditionally include templates if they exist but I wanted to use a variable to store the template name like you can do with the regular {% include %} tag.
Here's my solution which I've used with Django 1.7:
from django import template
from django.template.loader_tags import do_include
register = template.Library()
class TryIncludeNode(template.Node):
"""
A Node that instantiates an IncludeNode but wraps its render() in a
try/except in case the template doesn't exist.
"""
def __init__(self, parser, token):
self.include_node = do_include(parser, token)
def render(self, context):
try:
return self.include_node.render(context)
except template.TemplateDoesNotExist:
return ''
#register.tag('try_include')
def try_include(parser, token):
"""
Include the specified template but only if it exists.
"""
return TryIncludeNode(parser, token)
In a Django template it might be used like this:
{% try_include "template-that-might-not-exist.html" %}
Or, if the template name is in a variable called template_name:
{% try_include template_name %}
include accepts variables:
{% include template_name %}
so you could do the check in your view.