Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get type of Django form widget from within template

I'm iterating through the fields of a form and for certain fields I want a slightly different layout, requiring altered HTML.

To do this accurately, I just need to know the widget type. Its class name or something similar. In standard python, this is easy! field.field.widget.__class__.__name__

Unfortunately, you're not allowed access to underscore variables in templates. Great!

You can test field.field.widget.input_type but this only works for text/password <input ../> types. I need more resolution that that.

To me, however difficult it might look, it makes most sense to do this at template level. I've outsourced the bit of code that handles HTML for fields to a separate template that gets included in the field-loop. This means it is consistent across ModelForms and standard Forms (something that wouldn't be true if I wrote an intermediary Form class).

If you can see a universal approach that doesn't require me to edit 20-odd forms, let me know too!

like image 233
Oli Avatar asked Nov 27 '09 17:11

Oli


2 Answers

Making a template tag might work? Something like field.field.widget|widget_type

Edit from Oli: Good point! I just wrote a filter:

from django import template register = template.Library()  @register.filter('klass') def klass(ob):     return ob.__class__.__name__ 

And now {{ object|klass }} renders correctly. Now I've just got to figure out how to use that inside a template's if statement.

Edit from Oli #2: I needed to use the result of that in an if statetement in-template, so I just shifted all that logic into the templatetag. Magic. Thanks for poking me in the right direction.

like image 50
rinti Avatar answered Oct 21 '22 03:10

rinti


Following up on the accepted answer - the enhanced if tag in Django 1.2 allows you to use filters in if tag comparisons. So you could now do your custom html/logic in the template like so:

<ul> {% for field in form.fields %}   <li>     {% if field.field.widget|klass == "Textarea" %}     <!-- do something special for Textarea -->     <h2>Text Areas are Special </h2>     {% else %}             {{ field.errors }}       {{ field.label_tag }}       {{ field }}     {% endif %}    </li> {% endfor %} </ul> 
like image 45
zlovelady Avatar answered Oct 21 '22 03:10

zlovelady