Search code examples
djangoclassmodelphone-number

how can i add phone number field from class profile to class user?


I need to add phone number into my required model's field, so I'm doing this but is not working correctly so if everyone knows how can I add a Phone number, please help me:

#models.py

    from django.db import models
        from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
        from phonenumber_field.modelfields import PhoneNumberField
        
        
        class UserManager(BaseUserManager):
            def create_user(self, phone_number, email, password=None, is_active=True, is_staff=False, is_admin=False):
                if not email:
                    raise ValueError("User Must have an Email Address")
                if not password:
                    raise ValueError("User Must have a Password")
                if not phone_number:
                    raise ValueError("User Must have a Phone Number")
                user_obj = self.model(email=self.normalize_email(email))
                user_obj.set_password(password)  # change user password
                user_obj.phone_number(phonenumber_field)
                user_obj.staff = is_staff
                user_obj.active = is_active
                user_obj.admin = is_admin
                user_obj.save(using=self._db)
                return user_obj
        
            # staff user
            def create_staffuser(self, email, password=None):
                user = self.create_user(
                    email,
                    password=password,
                    phone_number=PhoneNumberField,
                    is_staff=True
                )
                return user
            # admin user
        
            def create_superuser(self, email, password=None):
                user = self.create_user(
                    email,
                    password=password,
                    phone_number=PhoneNumberField,
                    is_staff=True,
                    is_admin=True
                )
                return user
        
        
        class User(AbstractBaseUser):
            email = models.EmailField(max_length=255, unique=True)
            # full_name = models.CharField(max_length=255, blank=True, null=True)
            active = models.BooleanField(default=True)  # can log in
            staff = models.BooleanField(default=False)  # staff user non super user
            admin = models.BooleanField(default=False)  # super user
            timestamp = models.DateTimeField(auto_now_add=True)
            phone_number = PhoneNumberField()
        
            USERNAME_FIELD = 'email'  # username
            REQUIRED_FIELDS = []  # FULL_NAME
            object = UserManager()
        
            def __str__(self):
                return self.email
        
            def get_full_name(self):
                return self.email
        
            def get_short_name(self):
                return self.email
        
            def has_perm(self, perm, obj=None):
                return True
        
            def has_module_perms(self, app_label):
                return True
        
            @property
            def is_staff(self):
                return self.staff
        
            @property
            def is_admin(self):
                return self.admin
        
            @property
            def is_active(self):
                return self.active
        
        
        class Profile(models.Model):
            user = models.OneToOneField(User, on_delete=models.CASCADE)

I wanna add phone number in class profile and include this to the required field on user class, but I cant

every time i have error : raise TypeError("Can't convert %s to PhoneNumber." % type(value).name) TypeError: Can't convert int to PhoneNumber.


Solution

  • You can't add a ModelField class to an attribute. Instead try to pass the value through method arguments. As per documentation, you should be able to pass the value if the field is required.

    So, update your manager method like this:

    class UserManager(BaseUserManager):
        def create_user(self, email, phone_number, password=None, is_active=True, is_staff=False, is_admin=False):
            if not email:
                raise ValueError("User Must have an Email Address")
            if not password:
                raise ValueError("User Must have a Password")
            if not phone_number:
                raise ValueError("User Must have a Phone Number")
            user_obj = self.model(email=self.normalize_email(email))
            user_obj.set_password(password)  # change user password
            user_obj.phone_number = phone_number
            user_obj.staff = is_staff
            user_obj.active = is_active
            user_obj.admin = is_admin
            user_obj.save(using=self._db)
            return user_obj
    
        # staff user
        def create_staffuser(self, email, phone_number, password=None):
            user = self.create_user(
                email,
                password=password,
                phone_number=phone_number,
                is_staff=True
            )
            return user
        # admin user
    
        def create_superuser(self, email, phone_number, password=None):
            user = self.create_user(
                email,
                password=password,
                phone_number=phone_number,
                is_staff=True,
                is_admin=True
            )
            return user
    

    And add phone_number to required fields in model:

    REQUIRED_FIELDS = ['phone_number']