Django: UNIQUE constraint failed: users_customuser.email

Viewed 245

i keep getting this error when i try to register for the second time i have tried multiple possible solutions but i keep getting it anyway any help ?

IntegrityError at /registration/transporteur

this is my code: here i try to have multi type users

models.py

class CustomUser(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length= 15, )
    first_name = models.CharField(max_length= 15)
    last_name = models.CharField(max_length= 15)
    email = models.EmailField(_('email address'),unique= True,)
    phone_number = models.CharField(max_length= 15)
    address = models.CharField(verbose_name = "Address", max_length= 50, null = True, blank= True)
    # profile_picture = models.ImageField(null = True)
    # longitude = models.CharField(verbose_name = "Longitude", max_length= 100, null = True, blank= True)
    # lagitude = models.CharField(verbose_name = "Lagitude", max_length= 100, null = True, blank= True)

    date_joined = models.DateTimeField(auto_now_add=True)
    last_login = models.DateTimeField(auto_now=True)
    is_transporteur = models.BooleanField(default= False)
    is_client = models.BooleanField(default= False) 
    is_staff = models.BooleanField(default= False)
    is_superuser = models.BooleanField(default= False)
    is_active = models.BooleanField(default= False)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["first_name", "last_name", "username",  "phone_number", "address"]
    objects = CustomUserManager()

    def __str__(self):
        return self.username
    def has_perm(self, perm: str, obj: None):
        return self.is_admin
    def has_module_perms(self, app_label):
        return True


class Trasporteur(CustomUser):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name="trasporteur_account")
    matricule = models.CharField(max_length = 20, blank=True, null=True)
    car_type = models.CharField(max_length = 20, choices = CAR_tYPES)
    rating = models.IntegerField(blank=True, null = True)
    current_location = models.CharField(max_length = 20, blank=True, null=True)
    is_on_travail = models.BooleanField(default=False)
    bio = models.TextField()
    # last_transports = models.ManyToManyField('transport_services.TrasportService', on_delete=models.CASCADE, related_name="trasporteur_transports")

    def __str__(self):
        return self.user.username

class Client(CustomUser):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name="client_account")
    current_location = models.CharField(max_length = 20, blank=True, null=True)
    # last_transports = models.ManyToManyField('transport_services.TrasportService', on_delete=models.CASCADE, related_name="client_transports")

    def __str__(self):
        return self.user.username

managers.py

class CustomUserManager(BaseUserManager):

    def create_user(self, username, email, password, **extra_fields):

        if not username:
            raise ValueError(_('The username must be set'))
        if not email:
            raise ValueError(_('The Email must be set'))
        
        username = username
        email = self.normalize_email(email)
        user = self.model(username = username, email = email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, username, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))
        return self.create_user(username, email, password, **extra_fields)

serializers.py there is a separate registration and retrieve serializers for each class and the custom user one is just for test it is also the main one

class CustomUserSerializer(serializers.ModelSerializer):

    class Meta:
        model = CustomUser
        fields = '__all__'


class TransporteurSerializer(serializers.ModelSerializer):
    user = serializers.CharField(read_only=True,)
    class Meta:
        model = Trasporteur
        fields = '__all__'
    

class ClientSerializer(serializers.ModelSerializer):
    user = serializers.CharField(read_only=True,)
    class Meta:
        model = Client
        fields = '__all__'
    

class TransporteurCustomRegistrationSerializer(RegisterSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True,)
    first_name = serializers.CharField(required=True)
    last_name = serializers.CharField(required=True)
    phone_number = serializers.CharField(required=True)
    address = serializers.CharField(required=True)
    matricule = serializers.CharField(required=True)
    car_type = serializers.ChoiceField(choices= CAR_tYPES)

    def get_cleaned_data(self):
            data = super(TransporteurCustomRegistrationSerializer, self).get_cleaned_data()
            extra_data = {
                'first_name' : self.validated_data.get('first_name', ''),
                'last_name' : self.validated_data.get('last_name', ''),
                'phone_number' : self.validated_data.get('phone_number', ''),
                'address' : self.validated_data.get('address', ''),
                'matricule' : self.validated_data.get('matricule', ''),
                'car_type' : self.validated_data.get('car_type', ''),
            }
            data.update(extra_data)
            return data

    def save(self, request):
        user = super(TransporteurCustomRegistrationSerializer, self).save(request)
        user.is_transporteur = True
        user.username = self.data.get('username')
        user.email = self.data.get('email')
        user.first_name = self.data.get('first_name')
        user.last_name = self.data.get('last_name')
        user.phone_number = self.data.get('phone_number')
        user.address = self.data.get('address')
        user.matricule = self.data.get('matricule')
        user.car_type = self.data.get('car_type')
        user.save()
        transporteur = Trasporteur(
            user=user,
            email=self.cleaned_data.get('email'), 
            first_name=self.cleaned_data.get('first_name'), 
            last_name=self.cleaned_data.get('last_name'), 
            phone_number = self.cleaned_data.get('phone_number'),
            address = self.cleaned_data.get('address'),
            matricule=self.cleaned_data.get('matricule'), 
            car_type=self.cleaned_data.get('car_type'),
            )
        transporteur.save()
        return user


class ClientCustomRegistrationSerializer(RegisterSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True,) 
    first_name = serializers.CharField(required=True)
    last_name = serializers.CharField(required=True)
    phone_number = serializers.CharField(required=True)
    address = serializers.CharField(required=True)
    
    def get_cleaned_data(self):
            data = super(ClientCustomRegistrationSerializer, self).get_cleaned_data()
            extra_data = {
                'first_name' : self.validated_data.get('first_name', ''),
                'last_name' : self.validated_data.get('last_name', ''),
                'phone_number' : self.validated_data.get('phone_number', ''),
                'address' : self.validated_data.get('address', ''),
            }
            data.update(extra_data)
            return data

    def save(self, request):
        user = super(ClientCustomRegistrationSerializer, self).save(request)
        user.is_client = True
        user.email = self.data.get('email')
        user.first_name = self.data.get('first_name')
        user.last_name = self.data.get('last_name')
        user.phone_number = self.data.get('phone_number')
        user.address = self.data.get('address')
        user.save()
        client = Client(
            user=user,
            email=self.cleaned_data.get('email'), 
            first_name=self.cleaned_data.get('first_name'), 
            last_name=self.cleaned_data.get('last_name'), 
            phone_number = self.cleaned_data.get('phone_number'),
            address = self.cleaned_data.get('address'),
            )
        client.save()
        return user

settings related to django rest auth

AUTH_USER_MODEL = 'users.CustomUser'

ACCOUNT_USER_MODEL_USERNAME_FIELD = 'username'
ACCOUNT_UNIQUE_USERNAME = True
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = False
ACCOUNT_USERNAME_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_EMAIL_VERIFICATION = 'optional'
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = '/?verification=1'
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = '/?verification=1'

SITE_ID = 1
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

thanks for your help

2 Answers

just try to catch exception where you are creating Trasporteur from user like You can catch exception where you are creating user with this methood hope it helps you ps ignore my intendation

 def save(self, request):
        try:

           user = super(TransporteurCustomRegistrationSerializer, 
       self).save(request)
           user.is_transporteur = True
    

        user.username = self.data.get('username')
        user.email = self.data.get('email')
        user.first_name = self.data.get('first_name')
        user.last_name = self.data.get('last_name')
        user.phone_number = self.data.get('phone_number')
        user.address = self.data.get('address')
        user.matricule = self.data.get('matricule')
        user.car_type = self.data.get('car_type')
        user.save()
        except IntegrityError:
             raise ValidationError("User with this email already exist")
       

       transporteur = Trasporteur(
            user=user,
            email=self.cleaned_data.get('email'), 
            first_name=self.cleaned_data.get('first_name'), 
            last_name=self.cleaned_data.get('last_name'), 
            phone_number = self.cleaned_data.get('phone_number'),
            address = self.cleaned_data.get('address'),
            matricule=self.cleaned_data.get('matricule'), 
            car_type=self.cleaned_data.get('car_type'),
            )
        transporteur.save()
        return user

Solved by removing the inheritance from custom user. You wouldn't inherit from the abstract class.

Trasporteur(CustomUser) => Trasporteur(models.Model):
Related