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.
Related
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.
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": "philipssevarist#gmail.com33w4dd636",
"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
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
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
I have this Serializer:
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = '__all__'
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
name = validated_data['name'],
id = validated_data['id'],
user = Person.objects.create(name=name,
password=validated_data['password'],
id=id)
return user
I thought that passwords are automatically saved as hashs in the database but with this serializer the password is saved in a raw format. How could I modify this to save the hash, not the raw version?
Edit. Here is my Person model and my UserManager:
class UserManager(BaseUserManager):
def create_user(self, name, password):
user.set_password(password)
user.save(using=self._db)
return user
class Person(AbstractBaseUser):
id = models.CharField(primary_key=True, unique=True, blank=False, max_length=100)
name = models.CharField(max_length=100, unique=True, null=False, blank=False)
USERNAME_FIELD = 'name'
REQUIRED_FIELDS = []
objects = UserManager()
As you can see, the name is here used as the username. Where do you define the password hashing, in serializer or in my models.py?
You should set the password like this.
user = Person(name=name, id=id)
user.set_password(validated_data['password'])
user.save()
set_password method takes care of hashing.
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