
TLT: How To Write a Custom Form Field For Django Forms
I wanted to change the way a user's field input was is stored inside of my database. My model is pretty simple, but it contains an EmailField
, which isn't so simple to normalize as far as I know. That's why Django has a built-in normalize_email
method in the UserManager
class. I've decided to create a custom field, however, to address this issue.
The Problem
Setting unique=True
inside of the EmailField
I've constructed doesn't cut it because the form input won't be properly validated. If a user submits foobar@foomail.com
and then submits FooBar@foomail.com
, a duplication error won't be raised. That's a problem, so I decided to somewhat normalize the field input by setting it to lowercase before it's saved in the database.
The Solution
To create a custom form field, you just inherit from the form field class you want to customize. In this case, I want to inherit forms.EmailField
.
Inside of forms.py
:
# Change email input to lowercase
class CustomEmailField(forms.EmailField):
def to_python(self, value):
return value.lower()
# Visitor Inquiry Form
class InquiryForm(forms.ModelForm):
email = CustomEmailField(required=True, max_length=200)
class Meta:
model = Visitor
fields = ['email', ]
You override to_python
in your field definition so that the string the person's entered is converted into a python object whenever it's accessed from the database or whenever it's assigned using our custom field. In this case, our to_python
method returns the value
it was provided into a lowercase string, which is what I wanted.
Conclusion
I now have a custom email field that converts the user input into a lowercase string. Now, even FOObar@foo.com
is considered to be a duplicate of foobar@foo.com
. That's what I wanted.
I miss you, Renee. Tough Thanksgiving.