I'm trying to create a user and link it with the user profile. But here is the problem. This is my profile model
class EcomUser(BaseModelMixin):
profile = models.OneToOneField(
settings.AUTH_USER_MODEL, unique=True, blank=True, null=True,
on_delete=models.CASCADE)
username = models.CharField(max_length=100, blank=True)
email = models.CharField(max_length=100, blank=True, null=True)
name = models.CharField(max_length=100, blank=True)
referral_code = models.CharField(max_length=10, blank=True)
signinId = models.CharField(max_length=20, blank=True)
GOOGLE = 'GOOGLE'
APPLE = 'APPLE'
MOBILE_NUMBER = 'mobile_number'
LOGIN_TYPES = (
(GOOGLE, 'GOOGLE'),
(APPLE, 'APPLE'),
(MOBILE_NUMBER, 'mobile_number')
)
loginType = models.CharField(max_length=15, choices=LOGIN_TYPES, default=MOBILE_NUMBER)
class Meta:
db_table = "ecom_user"
My user model:
class User(AbstractBaseUser, BaseModelMixin):
email = models.EmailField(
verbose_name='email_address',
max_length=255,
blank=True,
null=True
)
username = models.CharField(max_length=128, null=True,unique=True)
fullName = models.CharField(max_length=256, blank=True)
mobile_number = models.CharField(max_length=15, blank=True,unique=True)
is_superuser = models.BooleanField(default=False)
class Meta:
db_table = "users"
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = [] # Email & Password are required by default.
def get_full_name(self):
# The user is identified by their email address
return self.fullName
def __str__(self): # __unicode__ on Python 2
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
objects = UserManager()
and serializer.py
class UserRegisterSerializer(serializers.Serializer):
"""Normal serializer which accepts mobile number"""
mobile_number = serializers.CharField(max_length=10, min_length=10, required=True)
referral_code = serializers.CharField(max_length=10, min_length=10, required=True)
email = serializers.EmailField(max_length=255)
def validate_referral_code(self, referral_code):
if not re.match(r"^[\w]{10}$", referral_code):
raise serializers.ValidationError("Wrong Referral Code")
return referral_code
def validate_mobile_number(self, mobile_number):
if not re.match(r"^[\d]{10}$", mobile_number):
raise serializers.ValidationError("Please pass proper mobile number")
return mobile_number
class EcomUserSerializer(serializers.ModelSerializer):
profile_id = serializers.IntegerField(required=True)
mobile_number = serializers.CharField(max_length=10, min_length=10, required=True)
referral_code = serializers.CharField(max_length=10, min_length=10, required=True)
class Meta:
model = EcomUser
fields= ('profile_id','referral_code', 'mobile_number', 'loginType', 'signinId')
def create(self, data):
instance = EcomUser.objects.create(**data)
return instance
views.py
@api_view(['POST'])
def registration(request):
try:
local_reponse = {
"status": False,
"message": "",
"code": status.HTTP_400_BAD_REQUEST,
"data": []
}
data = request.data
print('1')
mobile_number = data.get('mobile_number', None)
referralCode = data.get('referralCode', '')
LoginType = data.get('LoginType')
signinId = data.get('signinId', '')
email = data.get('email', '')
print(f'{LoginType} --- {EcomUser.MOBILE_NUMBER}')
if LoginType == "mobile_number":
print('2')
exist_user = User.objects.filter(mobile_number=mobile_number).count()
if exist_user:
print('3')
local_reponse["message"] = msg.ALREADY_EXIST
return Response(local_reponse)
try:
print('not found')
registerd_user = User.objects.get(mobile_number=mobile_number)
print(f'{registerd_user} -- check')
if registerd_user:
print('register')
ecom = EcomUser.objects.get(profile_id=registerd_user.id)
if ecom:
local_reponse["message"] = msg.ALREADY_EXIST
except User.DoesNotExist:
print('4')
user = User.objects.create_ecom_user(mobile_number=mobile_number)
user.save()
print('is user create?')
if user:
print('yes')
info = {}
info['profile_id'] = user.id
info['referral_code'] = referralCode
info['mobile_number'] = mobile_number
info['LoginType'] = LoginType
info['signinId'] = signinId
ecom_serializer = EcomUserSerializer(data=info)
if not ecom_serializer.is_valid():
print('5')
local_reponse["message"] = ecom_serializer.error_messages
local_reponse["status"] = False,
return Response(local_reponse)
print(f'linked profile 1 ----' )
ecomuser_data = ecom_serializer.save()
print(f'linked profile 2 ---- ' )
ecomuser_id = ecomuser_data.id
print('linked profile 3' )
ecomuser = EcomUser.objects.get(id=ecomuser_id)
print('linked profile 4' )
ecom_serializer = EcomUserSerializer(ecomuser)
print('linked profile 5' )
context = ecom_serializer.data
print('linked profile 6' )
local_reponse = {
"status": True,
"message": msg.CREATED,
"code": status.HTTP_201_CREATED,
"data": context
}
print('linked profile 7' )
return Response(local_reponse)
except Exception as e:
print('7')
local_reponse["message"] = str(e)
return Response(local_reponse)
When I try to run API on postman. It showed "EcomUser() got an unexpected keyword argument 'mobile_number'" and the output in the terminal show below:
1
mobile_number --- mobile_number
2
not found
4
is user create?
yes
linked profile 1 ----
7
The user is created but can not link to the profile, any one can help?
CodePudding user response:
There's no mobile_number field in your EcomUser model. Thus when you call
ecomuser_data = ecom_serializer.save()
after adding
info['mobile_number'] = mobile_number
if fails, leaving you with the user and no profile. I guess is_valid() is only checking the fields it wants, not detecting the surplus, but the extra field causes the save to fail with the error shown. You've already added the field when creating the user, so you don't need it in the profile, so removing that second line should make things work.