Reputation: 57
I want to change the classes / attributes of the input fields of a ModelForm, but I'd like to do it from the template if possible.
Below is my solution for this, using the django django-widget-tweaks
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
{{form.title|add_class:"form-control"|attr:"placeholder:Title"|attr:"type:text"}}
</div>
<div class="form-group">
{{form.description|add_class:"form-control"|attr:"placeholder:Description"}}
</div>
<div class="form-group">
{{form.author|add_class:"form-control"|attr:"placeholder:Author"}}
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
My problem, is that this isn't very DRY, and I'm wondering if there's a better way to do this. I know django has looping over forms, but I'm not sure how I can integrate it while modifying the attributes.
Any help is appreciated.
Upvotes: 0
Views: 262
Reputation: 12100
You can take the placeholder and store it inside the field's help_text
field. With that out of the way, you can easily loop through the fields like so:
{% for field in form %}
<div class="form-group">
{{ field|add_class:"form-control"|attr:field.help_text }}
</div>
{% endfor %}
Unfortunately it's hard/impossible to use a filter as for the second argument, so you will need to set help_text
to 'placeholder:%s'
where %s
is your desired value.
If you're using a regular form, then set help_text
in the constructor. But if you're using model form, I think it would be best to create a new template tag that can create the 'placeholder:%s'
string for you from the field title:
@register.assignment_tag
def get_placeholder_arg(field):
return 'placeholder:%s' % field.label
Then your code would look like this:
{% for field in form %}
{% get_placeholder_arg field as arg %}
<div class="form-group">
{{ field|add_class:"form-control"|attr:arg }}
</div>
{% endfor %}
See the django documentation on custom template tags for details.
Upvotes: 2