lord stock
lord stock

Reputation: 1211

How to Validate Against Current User in Django?

I have following model

class User(AbstractBaseUser, PermissionsMixin):

    #: First and last name do not cover name patterns around the globe
    username = CharField(max_length=100,unique=True)
    email = models.EmailField(_('email address'), unique=True)
    full_name = TitleCharField(max_length=100)
    phone_number = PhoneNumberField()
    referred_by = models.ForeignKey('self', on_delete=models.CASCADE)
    is_member = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

Scenario is same user cannot be a user and referred by user. what I have done so far is

def clean(self):
    if self == self.referred_by:
        raise DjangoValidationError({'referred_by': _('Same user cannot be referred by user')})

I don't feel I am doing right what shall I do?

Upvotes: 1

Views: 212

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477180

You can make it slightly more efficient by cleaning this with the primary key of the referred_by, since that avoids an extra query. Furthermore you should call the super().clean() such that validations on parent class(es) are also performed, and you can also try to enforce this at the database side with Django's constraint framework [Django-doc]:

from django.core.exceptions import ValidationError
from django.db.models import F, Q

class User(AbstractBaseUser, PermissionsMixin):
    # …
    
    def clean(self, *args, **kwargs):
        if self.pk == self.referred_by_id:
            raise ValidationError('Can not refer to itself!')
        return super().clean(*args, **kwargs)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=~Q(pk=F('referred_by_id')),
                name='age_gte_18'
            )
        ]

Upvotes: 1

Related Questions