﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
21370	"Add new generic ""getter"" filter"	Emanuele Bertoldi	nobody	"Very often happens we have some arbitrary objects in the template context and we want to retrieve some of their data based on some other variables.

So, I propose to add a generic '''getter''' filter with a very basic API:

{{{
{{ obj|get:attr_name }}
}}}

'''i.e. Access to model data based on a dynamic list of fields'''

{{{
<table>
    {% for obj in object_list %}
    <tr>
        {% for f in field_list %}
        <td>{{ obj|get:f }}</td>
        {% endfor %}
    </tr>
    {% endfor %}
</table>
}}}

'''i.e. Access to dict values based on a dynamic list of keys'''

{{{
{% for key in key_list %}
{{ dict|get:key }}
{% endfor %}
}}}

'''i.e. Access to a variable index of a list'''

{{{
{{ list|get:var_index }}
}}}

The last use case is the only which is ('''maybe, I'm not sure''') currently possible, using nested ""slice"" and ""first/last"" filters, but it's a lot more verbose and error-prone. Otherwise you have to use forloops with index checking, which is computation-heavy and really verbose on the code side.

In the built-in library, for example, there's already a '''get_digit''' filter, which looks very restricted to just one use-case and could be covered by this, more generic (and useful), filter.

The following is a basic '''untested''' implementation:

{{{
@register.filter
def get(obj, attr_name):
    """"""Returns the attr value for the given object.

    Example usage: {{ object|get:""pk"" }}
    """"""
    if isinstance(obj, dict):
        return obj.get(attr_name, """")

    elif isinstance(obj, (list, tuple))
    and (isinstance(attr_name, int)
         or attr_name.isdigit()):
        return obj[attr_name]

    elif hasattr(obj, attr_name):
        value = getattr(obj, attr_name)
        if callable(value):
            return value()
        return value

    return """"
}}}"	New feature	closed	Template system	dev	Normal	wontfix			Accepted	0	0	0	0	0	0
