Django - How to add html attributes to forms on templates
开发者_开发技巧Suppose I have the following template:
<div id="openid_input_area">
{{ form.openid_identifier }}
<input name="bsignin" type="submit" value="{% trans "Sign in" %}">
</div>
How can I add a css class to form.openid_identifier?
As I am adhering to the SOC principles and I expect designers to improve the templates I do NOT want to do this on the form model but on the template itself.
I couldn't find anything on this on the docs. Is there a way to do this on the template?
I've managed to code a simple solution to my problem:
I wrote a custom template tag:
from django import template
register = template.Library()
def htmlattributes(value, arg):
attrs = value.field.widget.attrs
data = arg.replace(' ', '')
kvs = data.split(',')
for string in kvs:
kv = string.split(':')
attrs[kv[0]] = kv[1]
rendered = str(value)
return rendered
register.filter('htmlattributes', htmlattributes)
And all I have to do at the template is:
{{ form.openid_identifier|htmlattributes:"class : something, id: openid_identifier" }}
I don't know of any other way in plain Django. Shortcuts like form.field
or form.as_p
really get you started, but in the end one can fall back on plain html. That's how I see it. Not to say that there isn't any need for more control about rendering. I remember reading this discussion about form rendering on the Django mailing list.
Simon Willison is/was working on a library to give designers more control, you can find its source on github. It's a bit older, so it might not even work anymore. But regarding your question, this example looks like it could be of use to you:
{% field form.name class="myclass" %}
<!-- renders as -->
<input type="text" name="name" id="id_name" class="myclass">
Actually this functionality should be easy to achieve. You need a template tag that accepts a form field, updating the widgets attributes (those you can set on the form already) and render the field.
Iterating over a form yields instances of BoundField
, that renders itself with its __unicode__
method. You would need to pass all keyword arguments to the widgets render function. A draft of this idea:
@register.simple_tag
def field(boundfield, **kwargs):
if self.field.show_hidden_initial:
return self.as_widget(attrs=kwargs) + self.as_hidden(only_initial=True)
return self.as_widget(attrs=kwargs)
精彩评论