from functools import wraps


def unique_boolean(field, subset=[]):
    """
    Allows to specify a unique boolean for a model.
    """
    def cls_factory(cls):
        def factory(func):
            @wraps(func)
            def decorator(self):
                kwargs = { field: True }
                for arg in subset:
                    if getattr(self, arg):
                        kwargs[arg] = getattr(self, arg)
                if getattr(self, field):
                    try:
                        tmp = self.__class__.objects.get(**kwargs)
                        if self != tmp:
                            setattr(tmp, field, False)
                            tmp.save()
                    except self.__class__.DoesNotExist:
                        if getattr(self, field) != True:
                            setattr(self, field, True)
                else:
                    if self.__class__.objects.filter(**kwargs).count() == 0:
                        setattr(self, field, True)
                return func(self)
            return decorator
        if hasattr(cls, 'save'):
            cls.save = factory(cls.save)
        return cls
    return cls_factory


# Example: keep the 'main' field unique for the phones of each user
@unique_boolean('main', subset=['user'])
class Phone(models.Model):
    user = models.ForeignKey(User)
    main = models.BooleanField()