Django templates: value of dictionary key with a space in it - django

In a Django template, is there a way to get a value from a key that has a space in it?
Eg, if I have a dict like:
{"Restaurant Name": Foo}
How can I reference that value in my template? Pseudo-syntax might be:
{{ entry['Restaurant Name'] }}

There is no clean way to do this with the built-in tags. Trying to do something like:
{{ a.'Restaurant Name'}} or {{ a.Restaurant Name }}
will throw a parse error.
You could do a for loop through the dictionary (but it's ugly/inefficient):
{% for k, v in your_dict_passed_into_context %}
{% ifequal k "Restaurant Name" %}
{{ v }}
{% endifequal %}
{% endfor %}
A custom tag would probably be cleaner:
from django import template
register = template.Library()
#register.simple_tag
def dictKeyLookup(the_dict, key):
# Try to fetch from the dict, and if it's not found return an empty string.
return the_dict.get(key, '')
and use it in the template like so:
{% dictKeyLookup your_dict_passed_into_context "Restaurant Name" %}
Or maybe try to restructure your dict to have "easier to work with" keys.

You can use a custom filter as well.
from django import template
register = template.Library()
#register.filter
def get(mapping, key):
return mapping.get(key, '')
and within the template
{{ entry|get:"Restaurant Name" }}

Related

Get key, value pair from Django object in template

How do I get key,value pair from object from get_object_or_404 in template, passed from view to template as context?
#views.py
def detail(request):
unknown = get_object_or_404(UnknownModel)
return render(request, 'app/display.html', { 'some_data':unknown })
and in app/display.html, I've been trying various approaches:
{{ some_data }}
{{ some_data.keys }}
{{ some_data.items }}
{% for key, value in some_data.items %}
{{ key }} - {{ value }}
{% endfor %}}
but none work.
If I knew the fields, I can access easily as below, but that's not the case
{{ some_data.field_1 }}
In your case unknown is instance of UnknownModel model.
In template, you are trying to iterate over this instance fields, but items method works
for dictionaries, not for your model. You can provide items method in your model to return dictionary with fields that you want or use following snippet:
{% for key, value in some_data.__dict__.items %}
{{ key }} - {{ value }}
{% endfor %}}
Method above will display many internal data related to your instance. Another (better) way of doing this is to convert your model instance to the dictionary inthe view and then pass it to the template. To achieve that, you can use django.forms.models.model_to_dict method.
from django.forms.models import model_to_dict
def detail(request):
unknown = get_object_or_404(UnknownModel)
return render(request, 'app/display.html', {'some_data':model_to_dict(unknown)})

Django Custom Tag Conditional Logic

In this project I'm working with (I'm very new to Django), there are custom tags i.e. {{ custom_tag }} that a previous developer created.
In the HTML file, I find myself doing the following block of conditional logic many times in the same HTML file.
{% if custom_tag == "Blog Tag" %}
Blog
{% elif custom_tag == "About Tag" %}
About
{% else %}
etc...
{% endif %}
Are there ways that I can replace all of that conditional logic into something like {{ custom_tag|pretty }} or {{ pretty_custom_tag }}?
You can write your own criting a custom filter which would let you use {{ custom_tag|tag_pretty }}: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
For example:
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter
#stringfilter
def pretty_tag(value):
return value.rpartition(" ")[0]

print out django request.META in a template

I am trying to print out the values inside the request.META in a template but I cannot get it right. All I got is an error Could not parse the remainder: '[i]' from 'REQ_META[i]'
below is my code:
in my views.py
def index (request):
template = loader.get_template('app/index.html')
page_data = { 'REQ_META': request.META}
context = RequestContext(request, page_data)
return HttpResponse(template.render(context))
in index.html
{% for i in REQ_META %}
{{ i }} = {{ REQ_META[i] }} <br />
{% endfor %}
Well, the right way to inspect the request.META objects would be using pdb in the view, or using tools like django-debugtoolbar.
In my opinion, django debug toolbar is an extremely handy tools for debugging purposes.
Regardless, Your issue is, REQ_META is a dictionary, and the way to parse the elements of the dictionary is:
{% for k, v in REQ_META %}
{{ k }} = {{ v }} <br />
{% endfor %}
Documentation here
There is already an answer, but thought it could be useful for future use:
You just need to access the object like this {{ REQ_META.i }} instead of {{ REQ_META[i] }}
Another option is to use django pprint template filter
{{ REQ_META|pprint }}
Which will always print nicely dict objects (and any other python object)

Using Django filters as variables

I am wondering if we could use django filter as a variable where a python method formatting text can set the filter value which can be rendered by the template
The usual way filter works is like this
{{ html_text | safe }} or {{ plain_text | linebreaks }}
I want to set the values for filters 'safe'/'linebreaks' in a variable and render it like this
{{ text | filter_variable }}
Researched online, but couldn't figure it out, any help would be appreciated.
I second what Chris Pratt said, but I'd do it like this:
from django.template import defaultfilters
#register.filter
def apply_filter(value, filter):
return getattr(defaultfilters, filter)(value)
that way it works for any filter.
You can't do that, but you can create a custom filter that accepts a parameter:
from django.template import defaultfilters
#register.filter
def apply_filter(value, filter):
if filter == 'safe':
return defaultfilters.safe(value)
if filter == 'linebreaks':
return defaultfilters.linebreaks(value)
else:
# You might want to raise an exception here, but for example purposes
# I'll just return the value unmodified
return value
Then, in your template:
{{ text|apply_filter:filter_variable }}
This works if you have a few filters:
{% ifequal filter_variable 1 %}{{ text|safe }}{% endifequal %}
{% ifequal filter_variable 2 %}{{ text|linebreaks }}{% endifequal %}
{% ifequal filter_variable 3 %}{{ text|yourfilter }}{% endifequal %}

Use variable as dictionary key in Django template

I'd like to use a variable as an key in a dictionary in a Django template. I can't for the life of me figure out how to do it. If I have a product with a name or ID field, and ratings dictionary with indices of the product IDs, I'd like to be able to say:
{% for product in product_list %}
<h1>{{ ratings.product.id }}</h1>
{% endfor %}
In python this would be accomplished with a simple
ratings[product.id]
But I can't make it work in the templates. I've tried using with... no dice. Ideas?
Create a template tag like this (in yourproject/templatetags):
#register.filter
def keyvalue(dict, key):
return dict[key]
Usage:
{{dictionary|keyvalue:key_variable}}
You need to prepare your data beforehand, in this case you should pass list of two-tuples to your template:
{% for product, rating in product_list %}
<h1>{{ product.name }}</h1><p>{{ rating }}</p>
{% endfor %}
Building on eviltnan's answer, his filter will raise an exception if key isn't a key of dict.
Filters should never raise exceptions, but should fail gracefully. This is a more robust/complete answer:
#register.filter
def keyvalue(dict, key):
try:
return dict[key]
except KeyError:
return ''
Basically, this would do the same as dict.get(key, '') in Python code, and could also be written that way if you don't want to include the try/except block, although it is more explicit.
There is a very dirty solution:
<div>We need d[{{ k }}]</div>
<div>So here it is:
{% for key, value in d.items %}
{% if k == key %}
{{ value }}
{% endif %}
{% endfor %}
</div>