Satchel
Satchel

Reputation: 57

Looping through Django Templates

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

Answers (1)

Anonymous
Anonymous

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

Related Questions