django-email-validators

April 17, 2026 ยท View on GitHub

OpenSSF Scorecard

django-email-validators

no more invalid or disposable emails in your database.

Installation

  • Run pip install django-email-validators
  • Add django_email_validators to settings.INSTALLED_APPS
  • Restart your application server

Usage

Validators

  • ๐Ÿ—‘๏ธ validate_email_non_disposable
  • ๐ŸŒ validate_email_mx
  • โœ๏ธ validate_email_provider_typo
  • ๐Ÿ‘ค validate_email_unique_dot_insensitive

validate_email_non_disposable

Validates that the email is not from a disposable email provider (fast, offline check).

validate_email_mx

Validates that the email domain has valid MX records (slow, requires network access).

validate_email_provider_typo

Validates that the email domain is not a likely typo of a common email provider. Checks a one-character diff against 80+ common providers and verifies the domain has no valid MX records (prevents false positives).

Examples that will be caught:

  • user@gmai.com -> suggests user@gmail.com
  • user@gmail.co -> suggests user@gmail.com
  • user@yahooo.com -> suggests user@yahoo.com

validate_email_unique_dot_insensitive

Validates that the email is unique in the database, accounting for dot-insensitive providers (e.g. Gmail treats dots in the local part as insignificant, so fabio.caccamo@gmail.com and fabiocaccamo@gmail.com are the same inbox).

Accepts an optional exclude_pk argument to exclude the current user when updating an existing account, and an optional field argument (default: "email") to specify the model field name.

Examples that will be caught:

  • fabio.caccamo@gmail.com already exists โ†’ fabiocaccamo@gmail.com is rejected

Since this validator requires access to the model instance (to exclude it on update), it cannot be used directly in a field's validators=[...]. Call it explicitly in a form or serializer:

from django_email_validators import validate_email_unique_dot_insensitive

# Form example
class UserForm(forms.ModelForm):
    def clean_email(self):
        email = self.cleaned_data["email"]
        exclude_pk = self.instance.pk
        validate_email_unique_dot_insensitive(email, exclude_pk=exclude_pk)
        return email

Or via validate_unique on the model:

class User(models.Model):
    email = models.EmailField()

    def validate_unique(self, exclude=None):
        super().validate_unique(exclude=exclude)
        validate_email_unique_dot_insensitive(self.email, exclude_pk=self.pk)

Usage

Note: validate_email_unique_dot_insensitive requires access to the model instance and cannot be used in validators=[...]. See the dedicated section above for usage examples.

from django.db import models
from django_email_validators import (
    validate_email_non_disposable,
    validate_email_mx,
    validate_email_provider_typo,
)

class User(models.Model):
    email = models.EmailField(
        validators=[
            validate_email_non_disposable,
            validate_email_mx,
            validate_email_provider_typo,
        ]
    )

Extending the providers list for typo check

You can extend the list of common email providers used by validate_email_provider_typo by adding your own list in Django settings:

EMAIL_VALIDATORS_EXTEND_COMMON_PROVIDERS = [
    'hey.com',
]

Extending the dot-insensitive domains list

You can extend the list of dot-insensitive domains used by validate_email_unique_dot_insensitive by adding your own list in Django settings:

EMAIL_VALIDATORS_EXTEND_DOT_INSENSITIVE_DOMAINS = [
    'fastmail.com',
]

Testing

# clone repository
git clone https://github.com/fabiocaccamo/django-email-validators.git && cd django-email-validators

# create virtualenv and activate it
python -m venv venv && . venv/bin/activate

# upgrade pip
python -m pip install --upgrade pip

# install requirements
pip install -r requirements.txt -r requirements-test.txt

# install pre-commit to run formatters and linters
pre-commit install --install-hooks

# run tests
tox
# or
pytest

License

Released under MIT License.


Supporting

  • :star: Star this project on GitHub
  • :octocat: Follow me on GitHub
  • :blue_heart: Follow me on Bluesky
  • :moneybag: Sponsor me on Github

See also

  • django-admin-interface - the default admin interface made customizable by the admin itself. popup windows replaced by modals. ๐Ÿง™ โšก

  • django-cache-cleaner - clear the entire cache or individual caches easily using the admin panel or management command. ๐Ÿงน

  • django-colorfield - simple color field for models with a nice color-picker in the admin. ๐ŸŽจ

  • django-extra-settings - config and manage typed extra settings using just the django admin. โš™๏ธ

  • django-maintenance-mode - shows a 503 error page when maintenance-mode is on. ๐Ÿšง ๐Ÿ› ๏ธ

  • django-redirects - redirects with full control. โ†ช๏ธ

  • django-treenode - probably the best abstract model / admin for your tree based stuff. ๐ŸŒณ

  • python-benedict - dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities. ๐Ÿ“˜

  • python-codicefiscale - encode/decode Italian fiscal codes - codifica/decodifica del Codice Fiscale. ๐Ÿ‡ฎ๐Ÿ‡น ๐Ÿ’ณ

  • python-fontbro - friendly font operations. ๐Ÿงข

  • python-fsutil - file-system utilities for lazy devs. ๐ŸงŸโ€โ™‚๏ธ