Template tag attribute lookup with abstracted variable
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
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
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 -~--~~~~--~~--~--~---