'Django custom model Interger extrafield not saving in the database return None instead

my models

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):

        print(phone_number, 'phone_number')
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        

        user = self.model(
            email=self.normalize_email(email),
            **extra_fields
        )

        user.phone_number = phone_number

        # user.phone_number = 333333

        print(user, 'user')

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, email, password):
        """
        Creates and saves a staff user with the given email and password.
        """
        user = self.create_user(
            email,
            password=password,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        """
        Creates and saves a superuser with the given email and password.
        """
        user = self.create_user(
            email,
            password=password,
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    username = models.CharField(max_length=100, default="")
    phone_number = models.IntegerField(default=0, verbose_name='phoneNumber')
    is_active = models.BooleanField(default=True)
    staff = models.BooleanField(default=False) # a admin user; non super-user
    admin = models.BooleanField(default=False) # a superuser
    slug = models.SlugField(max_length=255, unique=True)


    objects = UserManager()

    
    def save(self, *args, **kwargs):
    
        print(self.phone_number, 'before') #this print statement return none
        if not self.slug:
            self.slug = slugify(utils.rand_slug() + "-" + self.username)
        super(User, self).save(*args, **kwargs)
        print(self.phone_number, 'after') #this print statement return none

    # notice the absence of a "Password field", that is built in.

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [] # Email & Password are required by default.

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):
        return self.email


    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        return self.staff

    @property
    def is_admin(self):
        "Is the user a admin member?"
        return self.admin

    @property
    def owner(self):
        return self.user

my serializer

class UserRegisterSerializer(ModelSerializer):
    password = CharField(style={'input_type':'password'}, write_only=True)
    token = SerializerMethodField(read_only=True)
    expires = SerializerMethodField(read_only=True)
    message = SerializerMethodField(read_only=True)
    status_code = SerializerMethodField(read_only=True)
    phone_number = IntegerField()

    class Meta:
        model =User
        fields = [
            'email', 
            'username',
            'phone_number',
            'token',
            'slug',
            'expires',
            'message',
            'status_code',
            'password'
        ]

        extra_kwargs = {'password': {'write_only':True}, 'email': {'required':True}}

    def validate_phone_number(self, value):
        print(value) #This print the actua phone_number serializer value
        
    def get_status_code(self, obj):
        data = 200
        return data

    def get_message(self, obj):
        return 'Thank you for registering. Please verify your email before continuing'

    def get_token(self, obj):
        user = obj
        token = get_tokens_for_user(user)
        return token

    def validate_email(self,value):
        qs = User.objects.filter(email__iexact=value)
        if qs.exists():
            raise ValidationError("User with this email already exists")
        return value


    def validate_username(self, value):
        qs = User.objects.filter(username__iexact=value)
        if qs.exists():
            raise ValidationError("User with this username already exists")
        return value

 
    def create(self, validated_data):
        user_obj = User(
            username=validated_data.get('username'),
            email=validated_data.get('email')
        )
        user_obj.set_password(validated_data.get('password'))
        user_obj.save()
        return user_obj


    def get_expires(self, obj):
        return timezone.now() + timedelta(minutes=5) - datetime.timedelta(seconds=200)

my Views

class RegisterAPIView(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserRegisterSerializer
    permission_classes = [AnonPermissionOnly]

after sending a post man request to that endpoint this is the response

{
    "email": "[email protected]",
    "username": "philipsd34d6364433564w3",
    "phone_number": 0,
    "token": {
        "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY1MjI2NDI4NSwiaWF0IjoxNjUyMTc3ODg1LCJqdGkiOiI3ZjBjYjBhZTY5YWE0YzIzYjU4YTc1MWQ3N2M3YWVmZiIsInVzZXJfaWQiOjMzfQ.gLderlN9eMSkjpvaIg6I3eIuiGvo6Xzs_1lhq9hvKQ8",
        "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjUyMTc4MTg1LCJpYXQiOjE2NTIxNzc4ODUsImp0aSI6IjEzNWJiOTNkN2I2YzRlNzlhOTgxM2I4ODA2ODEyNjJjIiwidXNlcl9pZCI6MzN9.US3prDUaNNY9bChNakzRFO8MUam_HIQ_w5UI9_vDIgc"
    },
    "slug": "vl1yyt-philipsd34d6364433564w3",
    "expires": "2022-05-10T10:19:45.407716Z",
    "message": "Thank you for registering. Please verify your email before continuing",
    "status_code": 200

Note:that phone_number returns 0 which is the default value

fortunately if i manuall add the phone number using my admin dashboard it works but when eve i try using a form or service like postman it doesn'work



Solution 1:[1]

i finally discovered what the problem was, so i be posting the answer so anyone who encounters it my find it useful, the problem is i was overiding the create method in my serializer, i passed in the email, password and username but not phone_number to the model create method, though the phone_number field in the forms was getting the value, it wasn't saving it to the database, because i wasn't creating it,

so the proper thing should have been

def create(self, validated_data):
        user_obj = User(
            username=validated_data.get('username'),
            email=validated_data.get('email'),
            phone_number = validated_data.get('phone_number')
        )
        user_obj.set_password(validated_data.get('password'))
        user_obj.save()
        return user_obj

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Henry Truth