I'm trying to create a form where I'm getting certain details from the user.
I have defined fields in forms.py
and I'm also defining other attributes like placeholder and css class using django widget
system. But it is showing me a TypeError
:
TypeError: __init__() got an unexpected keyword argument 'attrs'
Following is my code:
models.py
from django.db import models
class Contact(models.Model):
your_name = models.CharField(max_length=100)
your_email = models.EmailField()
your_subject = models.CharField(max_length=100)
your_comment = models.TextField(max_length=200)
def __str__(self):
return self.name
forms.py
from django.forms import ModelForm, TextInput, TextInput, EmailField
from .models import Contact
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = ('your_name', 'your_email', 'your_subject', 'your_comment')
widgets = {
'your_name' : TextInput(attrs={'placeholder': 'Name *', 'class': 'form-control'}),
'your_email' : EmailField(attrs={'placeholder': 'Email *', 'class': 'form-control'}),
'your_subject' : TextInput(attrs={'placeholder': 'Subject *', 'class': 'form-control'}),
'your_comment' : Textarea(attrs={'placeholder': 'Comment *', 'class': 'form-control'}),
}
I've read Django docs for Overriding default fields and also this question init() got an unexpected keyword argument 'attrs' but cannot fix the error.
I am quite new to Python and Django and would appreciate any help, thank you.
TL;DR:
EmailField
is a just that aField
which can't be set as a widget, if you tried you'd run into the below problem, you wantEmailInput
which is the widget forEmailField
.First,
TextInput
andTextarea
accept the keyword argumentattrs
in their__init__
. So, these are fine.Look at this line:
EmailField
is a subclass ofCharField
which in turn is a subclass ofField
. Throughout this hierarchyattrs
will be passed along until it hitsField
which doesn't acceptattrs
.For reference here's the
__init__
forField
:The
__init__
forCharField
:The
__init__
forEmailField
:There is a widget argument that is accepted in which you can place a widget that does accept the
attrs
keyword.