from django.core import exceptions
from django.db import models
class NullTrueField(models.NullBooleanField):
"""Allow only True or NULL (silently coerce False -> NULL).
This field type is useful when you have a field that you only want to allow 1
of. For example, a "primary" email address.
class Email(models.Model):
user = models.ForeignKey('auth.User')
primary = NullTrueField()
class Meta:
unique_together = ('user', 'primary')
By adding the ``unique_together`` constraint, we can enforce a single primary
email address per user (since NULL != NULL).
"""
description = "Boolean, Either True or None (no False allowed)."
__metaclass__ = models.SubfieldBase
def to_python(self, value):
"""Handle True/None normally, silently coerce False to None"""
if value is None:
return None
if value is True:
return True
if value in ('None',):
return None
if value in ('t', 'True', '1'):
return True
# Coerce False -> None
if value is False:
return None
if value in ('f', 'False', '0'):
return None
raise exceptions.ValidationError(
self.error_messages['invalid'],
code='invalid',
params={'value': value},
)
def get_prep_value(self, value):
value = super(NullTrueField, self).get_prep_value(value)
if bool(value):
return True
return None