Django: How do I add arbitrary html attributes to input fields on a form?
Solution 1
city = forms.CharField(widget=forms.TextInput(attrs={'autocomplete':'off'}))
Solution 2
Sorry for advertisment, but I've recently released an app (https://github.com/kmike/django-widget-tweaks) that makes such tasks even less painful so designers can do that without touching python code:
{% load widget_tweaks %}
...
<div class="field">
{{ form.city|attr:"autocomplete:off"|add_class:"my_css_class" }}
</div>
or, alternatively,
{% load widget_tweaks %}
...
<div class="field">
{% render_field form.city autocomplete="off" class+="my_css_class" %}
</div>
Solution 3
If you are using "ModelForm":
class YourModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(YourModelForm, self).__init__(*args, **kwargs)
self.fields['city'].widget.attrs.update({
'autocomplete': 'off'
})
Solution 4
If you are using ModelForm
, apart from the possibility of using __init__
as @Artificioo provided in his answer, there is a widgets
dictionary in Meta for that matter:
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
widgets = {
'name': Textarea(attrs={'cols': 80, 'rows': 20}),
}
Solution 5
I did't want to use an entire app for this thing. Instead I found the following code here https://blog.joeymasip.com/how-to-add-attributes-to-form-widgets-in-django-templates/
# utils.py
from django.template import Library
register = Library()
@register.filter(name='add_attr')
def add_attr(field, css):
attrs = {}
definition = css.split(',')
for d in definition:
if ':' not in d:
attrs['class'] = d
else:
key, val = d.split(':')
attrs[key] = val
return field.as_widget(attrs=attrs)
use the tag in the html file
{% load utils %}
{{ form.field_1|add_attr:"class:my_class1 my_class2" }}
{{ form.field_2|add_attr:"class:my_class1 my_class2,autocomplete:off" }}
Related videos on Youtube
User
Updated on July 08, 2022Comments
-
User almost 2 years
I have an input field that is rendered with a template like so:
<div class="field"> {{ form.city }} </div>
Which is rendered as:
<div class="field"> <input id="id_city" type="text" name="city" maxlength="100" /> </div>
Now suppose I want to add an
autocomplete="off"
attribute to the input element that is rendered, how would I do that? Oronclick="xyz()"
orclass="my-special-css-class"
? -
User almost 14 yearsOk thank you. In my case I am using ModelForm so I am not explicitly defining the form fields (e.g. class AddressForm(forms.ModelForm): class Meta: model = models.Address ) Does this mean I can't use ModelForm or is there something special I need to do?
-
User almost 14 yearsok nevermind, rtfm: docs.djangoproject.com/en/dev/topics/forms/modelforms
-
jmagnusson about 13 yearsNice app Mike, just what I was looking for!
-
James Lin over 12 yearsthe documentation does not tell you to add "widget_tweaks" into your installed app in settings, might be worth to put that in to the documentation.
-
Mikhail Korobov over 12 yearsHi James, it is not stressed but in the 'Installation' section there is already a note about adding 'widget_tweaks' to INSTALLED_APPS.
-
asgaines almost 10 yearsHmmm, this seems to overwrite the element descending from the original model if inheriting as modelform. Anyone know how to keep from doing this? I want to keep access to the model help_text attribute
-
Stuart Axon almost 10 years@InfinitelyLoopy inside the init for form, you can add some code to grab the field and modify its widgets attributes. Here is some I used earlier to modify 3 fields: ``` for field_name in ['image', 'image_small', 'image_mobile']: field = self.fields.get(field_name) field.widget.attrs['data-file'] = 'file' ```
-
Stuart Axon almost 10 yearsSorry for the bored formatting, I can never remember how to format code on S/O after being on github :/
-
Wilhelm Klopp over 9 yearsWhat about attributes that don't take arguments like 'required' and 'autofocus' ?
-
trpt4him almost 9 yearsTrying to figure out why this got less upvotes than the answer above... sometimes I think Django/Python developers just prefer the harder way of doing things...
-
Akhorus over 8 years@trpt4him Using the init approach is useful to create a Mixin or Base Class that you can re-use in other Forms. This is typicall in a medium to big-scale project. The Meta.widgets is great for a single Form. So, both are good answers.
-
Ljubisa Livac over 8 years@MikhailKorobov thank you so much for this app, it helped me a lot! This was just the right thing i was looking for. I needed a form from ModelForm and didn't want to manually insert this attributes to every single field (40 of them), so i elegantly managed to achieve same result in seconds :) This should be the accepted answer!
-
Mikael Lindlöf about 8 yearsGood! No need to explicitly define all widgets now.
-
Anuj TBE over 6 yearsI was planning to write such application. Thanks to saving my effort.
-
David Dahan over 6 yearsThis solution is bad because there is no separation of concerns. HTML attributes should not be written in python code IMO. Mikhail Korobov solution is superior.
-
David Dahan over 6 yearsThis should be the accepted answer, even if it's not the official solution. It's way better that writing HTML attributes in python code.
-
Katharine Osborne about 6 yearsThis is not useful if you need to extract info from the model that isn't accessible in the template to put into say, a data attribute.
-
utkarsh2k2 over 5 yearsWhat if there I am using the same form for create and edit and I want to disable the field only in edit?
-
Gregorio about 4 yearsI like this solution because we can manage HTML attributes in the V of the MVC: the template. @Katharine Osborne, you can pass to the template any info you need.
-
CutePoison about 3 yearsHow would you use it to set properties w/o values e.g "novalidate"?
-
run_the_race about 2 yearsJust to clarify, this does not work for
django.forms.Form
?