Performing a Getattr() Style Lookup in a Django Template

Performing a getattr() style lookup in a django template

I also had to write this code as a custom template tag recently. To handle all look-up scenarios, it first does a standard attribute look-up, then tries to do a dictionary look-up, then tries a getitem lookup (for lists to work), then follows standard Django template behavior when an object is not found.

(updated 2009-08-26 to now handle list index lookups as well)

# app/templatetags/getattribute.py

import re
from django import template
from django.conf import settings

numeric_test = re.compile("^\d+$")
register = template.Library()

def getattribute(value, arg):
"""Gets an attribute of an object dynamically from a string name"""

if hasattr(value, str(arg)):
return getattr(value, arg)
elif hasattr(value, 'has_key') and value.has_key(arg):
return value[arg]
elif numeric_test.match(str(arg)) and len(value) > int(arg):
return value[int(arg)]
else:
return settings.TEMPLATE_STRING_IF_INVALID

register.filter('getattribute', getattribute)

Template usage:

{% load getattribute %}
{{ object|getattribute:dynamic_string_var }}


django form dynamic attribute lookup

Change the getattribute.py as below:

import re
from django.forms import Form, ModelForm
from django import template
from django.conf import settings

numeric_test = re.compile("^\d+$")
register = template.Library()

def getattribute(value, arg):
"""Gets an attribute of an object dynamically from a string name"""
if hasattr(value, str(arg)):
return getattr(value, arg)
elif hasattr(value, 'has_key') and value.has_key(arg):
return value[arg]
elif numeric_test.match(str(arg)) and len(value) > int(arg):
return value[int(arg)]
elif issubclass(value.__class__, (Form, ModelForm)) and arg in value.fields:
return value[arg]
else:
return settings.TEMPLATE_STRING_IF_INVALID

register.filter('getattribute', getattribute)

You can see in 17th and 18th lines that expected for special condition, related to forms and returned related rendered widget ;)

Access a model's field by another field's value in a template in Django?

See this SO question.

Django use value of template variable as part of another variable name

First, you would need a custom template filter to mimic getattr() functionality, see:

  • Performing a getattr() style lookup in a django template

Then, you would need add template filter for string concatenation:

{% load getattribute %}

{% for i in 1234|make_list %}
{% with "answer_"|add:i as answer %}
{{ form|getattribute:answer }}
{% endwith %}
{% endfor %}

Accessing session variable based on variable in for loop django template

You should implement a custom template filter like this to have the ability to use getattr.

from django import template
register = template.Library()

@register.simple_tag
def get_object_property_dinamically(your_object, first_property, second_property):
return getattr(getattr(your_object, first_property), second_property)
{% load get_object_property_dinamically %}
{% for prod in products %}
<p>{% multiple_args_tag request.session.cart prod.name 'quantity' %}</p>
{% endfor %}

how do i access the values in a session dynamically using django?

You can make a custom template tag to look up by attribute like here
Performing a getattr() style lookup in a django template:

# app/templatetags/getattribute.py

import re
from django import template
from django.conf import settings

numeric_test = re.compile("^\d+$")
register = template.Library()

def getattribute(value, arg):
"""Gets an attribute of an object dynamically from a string name"""

if hasattr(value, str(arg)):
return getattr(value, arg)
elif hasattr(value, 'has_key') and value.has_key(arg):
return value[arg]
elif numeric_test.match(str(arg)) and len(value) > int(arg):
return value[int(arg)]
else:
return settings.TEMPLATE_STRING_IF_INVALID

register.filter('getattribute', getattribute)

Now change your template to

{% load getattribute %}

{% for book in book_list %}
{% if book.title in request.session %}
{{ request.session|getattribute:book.title }}
{% endif %}
{% endfor %}

This is a basic custom template tag example:

Django - Simple custom template tag example

and docs:

https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/

From what I remember from my django days should work

Django : Listing model field names and values in template

Unfortunately, you can't do lookups like that in the template engine.

You'll have to deal with that in the view.

def showdetails(request, template):
objects = newivr1_model.objects.all()

for object in objects:
object.fields = dict((field.name, field.value_to_string(object))
for field in object._meta.fields)

return render_to_response(template, { 'objects':objects },
context_instance=RequestContext(request))

Template

{% for object in objects %}
<tr>
{% for field, value in object.fields.iteritems %}
<td>{{ field }} : {{ value }}</td>
{% endfor %}
</tr>
{% endfor %}


Related Topics



Leave a reply



Submit