24

I am using django forms and I want to use Twitter Bootstrap's css in my html. so my template looks like this:

{% for field in form %}
    <div class="form-group">
        {{ field.label_tag }}<!--Same thing as : <label for="{{field.id_for_label}}"></label> -->

        <input type="{{field.type}}" class="form-control" id="{{field.auto_id}}" placeholder="Email">
      </div>
{% endfor %}

I can't figure out out to get the type value. {{field.type}} .

Is there any way to get the type of the input field in django templates?

Thanks in advance

Update: The reason I am asking this question is because I want to be able to apply bootstrap classes to the input element. But in Bootstrap3, to use the default css for input types you would have to add form-control class to the input element like so: <input type="text" class="form-control" id="{{field.auto_id}}" placeholder="">.

If I use django's field {{field}} then I can't add the form-control class. I hope this clarifies some things.

I also saw this app https://github.com/dyve/django-bootstrap3 that looks like it does what I wanted to do. It surprises me that django doesn't allow accessing the form type to allow more flexibility.

regmi
  • 366
  • 1
  • 3
  • 7
  • Typically, you would just do something like: `
    {{ field }}
    ` The type will be filled in automatically by Django. Do you need the type for some other purpose?
    – Anthony Hilyard Jul 22 '15 at 17:04
  • @AnthonyHilyard Yes. But in Bootstrap3, to use the default css for input types you would have to add form-control class to the input element like so: `` What I really wanted to do was to apply form-control class in the template itself. – regmi Jul 22 '15 at 18:46
  • Possible duplicate of [Get type of Django form widget from within template](http://stackoverflow.com/questions/1809874/get-type-of-django-form-widget-from-within-template) – Flimm Aug 12 '16 at 13:39

5 Answers5

42

According to https://stackoverflow.com/a/31538555/254553

You can use:

{{ [FIELD].field.widget.input_type }}

[FIELD] is your field name.

Chalist
  • 3,160
  • 5
  • 39
  • 68
10

I don't think you need to worry about the field_type. Django will itself handle that for you depending on the form field.

Lets say we have a ContactForm like:

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

Then {{form.subject}} will automatically create <input> element in the template.

<input id="id_subject" type="text" name="subject" maxlength="100" />

Similarly, {{form.message}} in the template will create:

<input type="text" name="message" id="id_message" />

Though if you really need to get the form field type in the template, you can create a custom template filter like below.

from django import template

register = template.Library()

@register.filter(name='field_type')
def field_type(field):
    return field.field.widget.__class__.__name__

Now, in your template, you need to do something like:

{{form.field_name|field_type}}

In the above example, {{form.message|field_type}} will return TextInput.

Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126
  • True! I wanted more flexibility with my input elements though. Mostly to be able to use bootstrap classes in the template itself. – regmi Jul 22 '15 at 18:48
  • Updated the ans with a custom template filter which will return the field_type. – Rahul Gupta Jul 22 '15 at 19:29
3

If you want to access the field type then refer to this answer.
If you want to override the default type of the field, use attrs parameter when defining the widget for the field.
Eg.

field_name = forms.CharField(widget=forms.Textarea(attrs={'type': 'custom type'}))

Also note that you can pass any key value pair to attrs and they will be used as attributes in the html tag when the form is rendered.

Community
  • 1
  • 1
Vinay Karanam
  • 41
  • 1
  • 4
2

I also had this problem. I used Django Widget Tweaks to add classes (https://github.com/kmike/django-widget-tweaks).

Then you can do something like this:

    {% for field in form %}
     <div class="form-group {% if field.errors %}has-error {% endif %}">    
        {% render_field field class="form-control" %}
        {% if field.errors %}
        <span class="help-block">{{ field.errors.0 }}</span>
        {% endif %}
    </div>
   {% endfor %}

I think another way of dealing with this is to use django crispy forms but I have not tried that yet.

Magda
  • 1,218
  • 3
  • 14
  • 31
0

You are able to override the __init__ method of the form in order to pass attributes to the HTML without having to know the type of field. Works with both standard forms and modelforms

class CoolForm(forms.Form):
    field_name = forms.CharField(...)

    def __init__(self, *args, **kwargs):
        super(CoolForm, self).__init__(*args, **kwargs)
        self.fields['field_name'].widget.attrs = {
            'class': 'form-control'
        }

You can pass any HTML attribute through to the template this way, for example 'placeholder': 'email@exam.pl'

Llanilek
  • 3,386
  • 5
  • 39
  • 65