Template tag attribute lookup with abstracted variable

2008-11-21 Thread Andy Young

I'm looking for an elegant way of stepping through my models from
within my template tags.

I have 3 model classes chained by many-to-many relationships, viz
Category --> Item --> Detail.  This model pertains to resume data,
e.g., Category='Education', Item='Univ1', Detail='Biology
coursework'.  Each model class has various subfields which I would
like to display on the final resume page.

I have tried various approaches involving {% for %} loops, and each
has resulted in failure.  Each of my attempts requires using a
variable name as a model's attribute lookup.  Unfortunately, it seem
the Django templating language attempts to access the variable's name,
not its value.

Approach 1):

I have pulled the field names from metadata in the view:

fields = []
for f in Item._meta.fields:
fields.append(f.column)

{% for c in categories %}
  {% for i in c.items.all %}
{% for f in fields %}
  {{ i.f }}
{% endfor %}
  {% endfor %}
{% endfor %}

There's no resulting output, indicating Django was looking for an "f"
attribute to the Item instance contained in "i".

I was thinking about using a {% with %} block to concatenate the value
of "f" to the end of the "i" Item instance.  It just seems incredibly
inelegant to have to explicitly list every field name I want
displayed.

Regards.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Template tag attribute lookup with abstracted variable

2008-11-21 Thread Malcolm Tredinnick


On Fri, 2008-11-21 at 12:06 -0800, Andy Young wrote:
> I'm looking for an elegant way of stepping through my models from
> within my template tags.
> 
> I have 3 model classes chained by many-to-many relationships, viz
> Category --> Item --> Detail.  This model pertains to resume data,
> e.g., Category='Education', Item='Univ1', Detail='Biology
> coursework'.  Each model class has various subfields which I would
> like to display on the final resume page.
> 
> I have tried various approaches involving {% for %} loops, and each
> has resulted in failure.  Each of my attempts requires using a
> variable name as a model's attribute lookup.  Unfortunately, it seem
> the Django templating language attempts to access the variable's name,
> not its value.

It is deliberate that Django's template language doesn't support
indirect attribute lookup. Helps to keep things simple (part of the
"keep programming out of templates" design goal). However, that's just
the goal of Django's core. You can easily write a template tag or a
filter to do this (I believe somebody already has something similar on
djangosnippets, but I don't have any link to it, since I never have a
need to do this).

An alternate approach is to write a template tag that takes the list of
field names as an argument (perhaps takes a variable containing the list
of field names) and then returns the list of values you want. So you
could write something like

{% get_fields c fields as my_values %}
{% for value in my_values %}
   ...
{% endfor %}

Here, I'm making up an API where the tag puts the result in the
my_values variable, so that you can subsequently loop over it. You could
store the values there, or a list of (name, value) pairs, or make it a
dictionary; whatever, you like.

Regards,
Malcolm



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Template tag attribute lookup with abstracted variable

2008-11-22 Thread Andy Young

On Nov 21, 7:03 pm, Malcolm Tredinnick <[EMAIL PROTECTED]>
wrote:
> It is deliberate that Django's template language doesn't support
> indirect attribute lookup. Helps to keep things simple (part of the
> "keep programming out of templates" design goal).

You're absolutely right about this, and I am increasingly seeing the
value here.  It not only keeps the templating system fast, but it
provides a lot of security as well.

> An alternate approach is to write a template tag that takes the list of
> field names as an argument (perhaps takes a variable containing the list
> of field names) and then returns the list of values you want. So you
> could write something like
>
>         {% get_fields c fields as my_values %}
>         {% for value in my_values %}
>            ...
>         {% endfor %}

A great suggestion, as I suppose I was a bit reticent at writing
custom template tags.  I went down this road, resulting in code that
revolved around the following:

"Usage: {% get_values item fields [as values] %}"

for f in fields:
values_dict[f] = getattr(item, f)

where fields was already a context variable provided by a custom {%
get_fields %} tag.

However, I then ran across this snippet: 
http://www.djangosnippets.org/snippets/411/
which defines a getattr filter.  I added a bit of code at the
beginning to determine if the argument was a string or a variable, and
voila!  I think the result is much more readable:

{% for i in items %}
  {% for f in fields %}
{{ f }}: {{ i|getattr:f }}
  {% endfor %}
{% endfor %}
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---