EcomUser() got an unexpected keyword argument 'mobile_number' - python-3.x

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?

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.

Related

django.db.utils.ProgrammingError: column accounts_account.username does not exist

I am getting this error after I was customizing my Customer User Model. and now I get this error when I try to login into the admin panel and when I try to create a superuser.
I tried to drop the postgresql database called skincareryland... but am getting an error on the password login... when I try to change the password I get this error.. ERROR: role "postgres" does not exist
I also tried going through these steps from an overstack post, but not having any luck fixing the problem... Comment out 'django.contrib.admin' from INSTALLED_APPS in settings.py and comment out # path('admin/', admin.site.urls) in urls.py
here is a better snapshot of my models.py code
here is a better snapshot of my settings.py code
from django.db import models
from django.contrib.auth.models import AbstractBaseUser,
BaseUserManager
class MyAccountManager(BaseUserManager):
def create_user(self, first_name, last_name, username, email,
password=None):
if not email:
raise ValueError('User must have an email address')
if not username:
raise ValueError('User must have an username')
user = self.model(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, first_name, last_name, email, username,
password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
password=password,
first_name=first_name,
last_name=last_name,
)
user.is_admin = True
user.is_active = True
user.is_staff = True
user.is_superadmin = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
username = models.CharField(max_length=50, unique=True)
email = models.EmailField(max_length=100, unique=True)
phone_number = models.CharField(max_length=50)
# required
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_superadmin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
objects = MyAccountManager()
def full_name(self):
return f'{self.first_name} {self.last_name}'
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, add_label):
return True
class UserProfile(models.Model):
user = models.OneToOneField(Account, on_delete=models.CASCADE)
address_line_1 = models.CharField(blank=True, max_length=100)
address_line_2 = models.CharField(blank=True, max_length=100)
profile_picture = models.ImageField(blank=True,
upload_to='userprofile')
city = models.CharField(blank=True, max_length=20)
state = models.CharField(blank=True, max_length=20)
country = models.CharField(blank=True, max_length=20)
def __str__(self):
return self.user.first_name
def full_address(self):
return f'{self.address_line_1} {self.address_line_2}'
Here is my Traceback error:
Maybe in your settings.py you need to add the line
AUTH_USER_MODEL = 'your_app.Account'
or
AUTH_USER_MODEL = 'Account'
depending on how you set up the project.
Also remove all migrations and drop the database, then do them again.

Django PostgreSQL - the password isn't saved to the database

I have a custom User model and a function in views.py to handle the registration. when I register a user with Postman for example all the user data is stored in the database correctly but the password -field remains empty. I think that causes the problem when I try to use a simple login -page - it never accepts my credentials (because there is no password in the database). Any ideas why the password isn't saved and how to fix it?
I have a function like this in views.py when registering a new user:
def register(response):
if response.method == 'POST':
form = RegisterForm(response.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db()
user.id = form.cleaned_data.get('id')
user.save()
username = form.cleaned_data.get('email')
password = form.cleaned_data.get('password')
user = authenticate(username=email, password=password)
return HttpResponse(status=201)
else:
form = RegisterForm()
return HttpResponse(status=400)
And this is my custom user model:
class UserManager(BaseUserManager):
def create_user(self, email, password):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('A user must have a email.')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
Edit. Here is my RegisterForm:
User = get_user_model()
class RegisterForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email', 'id', 'gender', 'height', 'weight']
def clean_email(self):
'''
Verify email is available.
'''
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean_id(self):
'''
Verify id is available.
'''
id = self.cleaned_data.get('id')
qs = User.objects.filter(id=id)
if qs.exists():
raise forms.ValidationError("id is taken")
return id
def clean(self):
'''
Verify both passwords match.
'''
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_2 = cleaned_data.get("password_2")
if password is not None and password != password_2:
self.add_error("password_2", "Your passwords must match")
return cleaned_data
And here is the model:
class CustomUser(AbstractBaseUser):
is_active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
gender = models.CharField(null=True, blank=True, max_length=20)
height = models.CharField(null=True, blank=True, max_length=3)
id = models.CharField(primary_key=True, unique=True, blank=False, max_length=100)
email= models.EmailField(max_length=100, unique=True, null=False, blank=False)
weight = models.CharField(max_length=3, null=True, blank=True)
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
objects = UserManager()
And soon after editing my question I noticed I was missing the save function from the RegisterForm class. Adding this solved the problem:
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password"])
if commit:
user.save()
return user

Django admin link at user model from another in list

In my django admin i have a model that link to user, i would have n my list create a link for pass to related user id editing page directly from connected models, i do:
class a_cards(models.Model):
CK_CHOICES = (
('A', 'Ambassador'),
('M', 'Medico'),
('P', 'Paziente'),
('S', 'Senator'),
)
c_num = models.CharField(max_length=200, unique=True,
null=True, blank=True, verbose_name="Numero card")
c_data = models.DateTimeField(auto_now=True)
c_type = models.CharField(
max_length=1, choices=CK_CHOICES, verbose_name="Tipo utenza")
c_email = models.CharField(max_length=200, unique=True,
null=True, blank=True, verbose_name="Notifica Email")
c_agente = models.ForeignKey(AgenteProfile, on_delete=models.CASCADE,
null=True, blank=True, related_name="ag_id", verbose_name="Agente")
c_user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE, verbose_name="Cliente" )
class Meta:
verbose_name = 'Cards'
verbose_name_plural = 'Cards'
def user_link(self):
if self.c_user:
return '%s' % (reverse("admin:auth_user_change", args=(self.c_user.id,)) , escape(self.c_user))
user_link.allow_tags = True
user_link.short_description = "User"
def __str__(self):
return self.c_num
in admin:
class cardAdmin(ImportExportModelAdmin):
list_filter = ('c_type',)
list_display = ('c_num', 'c_data', 'c_type', 'c_agente', 'user_link',)
...
but when i open my admin page i see the correct link but not in libk form:
where is the error?
why i can't have clickable link?
So many thanks in advance
you should use format_html for building HTML contents. so refactor your url generator method like;
class a_cards(models.Model):
....
def user_link(self):
if self.c_user:
return format_html('{text}', url=reverse("admin:auth_user_change", args=(self.c_user.id,)), text=self.c_user)
return "-"
user_link.short_description = "User"
user_link.allow_tags = True
from the docs;
All args and kwargs are passed through conditional_escape() before being passed to str.format().
so you do not need to specify extra escape().

Django Query data optimization

Recently, I watched Django and discovered the teaching videos of select_related and prefetch_related.
So I installed debug_toolbar and took a look at my website
I searched the database too many times on one page.
I must convert it to json and send it back to the front end
Can I still optimize?
Is this the only way to go?
Below is my model .
models.py
def get_upload_path(instance, filename):
return f'register/{instance.owner.job_number}/{filename}'
def image_upload_path(instance, filename):
date = datetime.datetime.strptime(instance.date, '%Y-%m-%d %H:%M:%S')
return f'image/{date.year}/{date.month}/{date.day}/{filename}'
class UserProfile(models.Model):
name = models.CharField(max_length=64)
department = models.CharField(max_length=32)
job_number = models.CharField(max_length=32, unique=True)
card_number = models.CharField(max_length=32, unique=True)
location = models.CharField(max_length=32)
date = models.DateTimeField()
class UserRegister(models.Model):
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
date = models.DateTimeField()
feature = ArrayField(models.FloatField(null=True, blank=True), null=True, blank=True, size=512)
image = models.ImageField(upload_to=get_upload_path)
class Meta:
db_table = 'UserRegister'
class UserImage(models.Model):
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
heat = models.CharField(max_length=8, blank=True, null=True)
date = models.DateTimeField()
image = models.ImageField(upload_to=image_upload_path)
punch_in = models.CharField(max_length=8, blank=True, null=True)
class Meta:
db_table = 'UserImage'
views.py
def get_db_data(db, page, limit, model):
data = []
paginator = Paginator(db, limit)
try:
page_object = paginator.page(page)
all_page = paginator.num_pages
for db_data in page_object:
images = []
for image in db_data.userregister_set.all():
try:
url = f'/static/uploads{image.image.url}'
except ValueError:
url = '/static/imgs/assets/none.jpg'
images.append({'id': image.id, 'url': url})
_ = {
'id': db_data.id,
'name': db_data.name,
'department': db_data.department,
'job_number': db_data.job_number,
'card_number': db_data.card_number,
'location': db_data.location,
'date': db_data.date.strftime('%Y-%m-%d %H:%M:%S'),
'images': images,
}
data.append(_)
result = {
'data': data,
'all_page': all_page,
'page': int(page)
}
return result
except EmptyPage as error:
# 該頁數沒資料。
return {'msg': 'Error'}
class Test(Views):
def get(self, request):
name = request.GET.get('name')
department = request.GET.get('department')
job_number = request.GET.get('job_number')
card_number = request.GET.get('card_number')
location = request.GET.get('location')
start_date = request.GET.get('start_date')
end_date = request.GET.get('end_date')
order = request.GET.get('order', default='DESC')
page = request.GET.get('page', default=1)
limit = request.GET.get('limit', default=25)
user_profile = UserProfile.objects.all().select_related()
if name:
user_profile = user_profile.filter(name=name)
if department:
user_profile = user_profile.filter(department=department_table.department)
if job_number:
user_profile = user_profile.filter(job_number=job_number)
if card_number:
user_profile = user_profile.filter(card_number=card_number)
if location:
user_profile = user_profile.filter(location=locations_table.location)
if start_date and end_date:
user_profile = user_profile.filter(date__range=[start_date, end_date])
if order == 'DESC':
data = get_db_data(db=user_profile.order_by('-date'), page=page, limit=limit, model='api')
else:
data = get_db_data(db=user_profile.order_by('date'), page=page, limit=limit, model='api')
response = JsonResponse(data)
# return response # This is the response I want to return, but now I need to use `debug_toolbar`, so I return an empty page to facilitate my reading `debug_toolbar`.
return render(request, 'User/test1.html')
return JsonResponse(data) is what I want to return, but now I need to use debug_toolbar, so I return to an empty page to facilitate reading debug_toolbar.
Use select_related() or prefetch_related().
Put the associated parameters into.
can speed up the ORM.

drf CustomUser matching query does not exist

i'm working on mobile app with customuser. i'm trying to send otp on mail while creating user and set is_verify to false and after that user verify with otp then is_verify will set to true but if user does't verify otp add closes app then again while signup we're adding check if user exist and is_verified to true then return already exist otherwise create user and send otp again. so i'm getting error on if user doesnotexist then its showing this error:
users.models.CustomUser.DoesNotExist: CustomUser matching query does not exist.
and its getting this error from except customuser.doesnotexist block
models.py:
class CustomUser(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(_('first name'), max_length=50)
last_name = models.CharField(_("last name"), max_length=50)
email = models.EmailField(_('email address'), unique=True)
mobile_number = models.CharField(
_('mobile number'), max_length=12, unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
user_type = models.IntegerField(_("user_type"))
otp = models.CharField(_("otp"), max_length=10, default="0")
is_verified = models.BooleanField(default=False)
USER_TYPE_CHOICES = (
(1, 'users'),
(2, 'courier'),
(3, 'admin'),
)
user_type = models.PositiveSmallIntegerField(
choices=USER_TYPE_CHOICES, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserMananager()
def __str__(self):
return self.email
seralizers.py:
class CustomUserSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer(required=False)
password = serializers.CharField(write_only=True, required=False)
class Meta:
model = CustomUser
fields = ('id', 'first_name', 'last_name', 'email',
'mobile_number', 'password', 'is_active', 'user_type', 'otp', 'profile')
def create(self, validated_data):
profile_data = validated_data.pop('profile', None)
user = CustomUser(
email=validated_data['email'],
mobile_number=validated_data['mobile_number'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name'],
user_type=validated_data['user_type'],
)
user.set_password(validated_data['password'])
def random_with_N_digits(n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
otp = random_with_N_digits(5)
user.otp = otp
user.is_active = False
user.save()
subject = 'Please Confirm Your Account'
message = 'Your 5 Digit Verification Pin: {}'.format(otp)
email_from = '*****'
recipient_list = [str(user.email), ]
send_mail(subject, message, email_from, recipient_list)
#user = CustomUser.objects.create(**validated_data)
# if profile_data:
UserProfile.objects.create(
user=user, age=None, gender=None)
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile', None)
# update user data
instance.first_name = validated_data.get(
'first_name', instance.first_name)
instance.last_name = validated_data.get(
'last_name', instance.last_name)
instance.email = validated_data.get('email', instance.email)
instance.save()
password = validated_data.get('password', None)
if password:
instance.set_password(password)
instance.save()
return instance
views.py:
#api_view(["POST"])
#permission_classes((AllowAny,))
def register(request):
try:
user = CustomUser.objects.get(
email=request.data.get('email'), is_verified=True)
if user:
return Response({'message': 'Customer with this mail already exists', 'status': 'false', 'status_code': status.HTTP_401_UNAUTHORIZED, 'currentTimeStamp': datetime.datetime.now()}, status=status.HTTP_400_BAD_REQUEST)
except CustomUser.DoesNotExist:
serializer = CustomUserSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
token, created = Token.objects.get_or_create(user=user)
current_time = datetime.datetime.now()
return Response({'status_code': status.HTTP_200_OK, 'status': 'true', 'currentTimeStamp': current_time, 'message': 'User registered successfully, OTP sent to your Mail', 'data': {'id': user.id, 'token': token.key, 'user_type': user.user_type}}, status=status.HTTP_200_OK)
return Response({'message': serializer.errors, 'status': 'false', 'status_code': status.HTTP_401_UNAUTHORIZED, 'currentTimeStamp': datetime.datetime.now()}, status=status.HTTP_400_BAD_REQUEST)
it seems it showing error after after this check:
user = CustomUser.objects.get(email=email)
but as i have already created the user with serializer.save so it should be getting the current user
edit:
i solved it by saving serailizer.save object to user but i'm still stuck in this situation as i want to send mail everytime until user is_verified is true but after first registration its showing customuser already exist . its only checking email field as its comes with django is there any to override this so it should show customuser exist only if email and is_verified is true

Resources