Unique on CharField when blank=True

I recently ran into a situation where I wanted to make an EmailField unique. The problem was that the field had blank set to True so the field couldn't be unique because when testing uniqueness Django (and AFAIK the underlying databases) consider '' to match ''. This is differnet than when you have null=True as well because django and the underlying database do not consider None and None to be a match when checking for uniqueness.

After a bit of googling I found that I was not the first person to have this sort of trouble.

The Code

Custom Field

from django.db import models


class NullableEmailField(models.EmailField):
    description = "EmailField that stores NULL but returns ''"
    __metaclass__ = models.SubfieldBase
    def to_python(self, value):
        if isinstance(value, models.EmailField):
            return value
        return value or ''
    def get_prep_value(self, value):
        return value or None

Model Field Definition

email = NullableEmailField(_('e-mail address'), blank=True, null=True, default=None, unique=True)

Credits

mightyhal on Stackoverflow

Comments