Integrity Error: NOT NULL constraint failed: users_profile.user_id - django

I want to implement update User Profile,in django rest framework.
I am getting the above mentioned error, no matter what I try and change in my code.
Below is the the code for my user serializers, user model and api views.
users/api/serializers.py:
from rest_framework import serializers
from ..models import User,Profile
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username','first_name','last_name','phone','id')
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta:
model = Profile
fields = ('user', 'bio', 'image')
def update(self,instance,validated_data):
user_data = validated_data.pop('user',{})
user = instance.user
instance.bio = validated_data.get('bio',instance.bio)
instance.image = validated_data.get('image',instance.image)
instance.save()
return instance
Is there anything wrong in my serializer, cause I tried hardcoding and saving a particular user profile also by using for ex: instance.user.id = 21 and then saving it, but i get the same error
Is there anything wrong in my serializer, cause I tried hardcoding and saving a particular user profile also by using for ex: instance.user.id = 21 and then saving it, but i get the same error
users/models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
import os
import random
import string
class MyAccountManager(BaseUserManager):
def create_user(self,phone,username,first_name,last_name):
if not phone:
raise ValueError("Users must have a valid phone number")
if not username:
raise ValueError("Users must have a valid username")
if not first_name:
raise ValueError("Users must have a valid First Name")
if not last_name:
raise ValueError("Users must have a valid last name")
user = self.model(
phone=phone,
username=username,
first_name=first_name,
last_name=last_name
)
user.save(using=self._db)
return user
def create_superuser(self,username,phone,first_name,last_name,password = None):
user = self.create_user(
username=username,
phone=phone,
first_name=first_name,
last_name=last_name,
)
user.set_password(password)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
phone = models.CharField(unique=True,max_length=20)
username = models.CharField(max_length=50,unique=True)
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=30, blank=True)
date_joined = models.DateTimeField(verbose_name='date_joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last_login', auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
otp = models.CharField(max_length=10,default='')
USERNAME_FIELD = 'phone'
REQUIRED_FIELDS = ['username','first_name','last_name']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self,perm,obj = None):
return self.is_admin
def has_module_perms(self,app_label):
return True
class Profile(models.Model):
user = models.OneToOneField(User,on_delete = models.CASCADE)
bio = models.CharField(max_length=140)
image = models.ImageField(default='default.jpg',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username}'
users/api/views.py
from rest_framework import status
from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.views import APIView
from .serializers import UserSerializer,UserProfileSerializer
from ..models import User,Profile
from django_filters.rest_framework import DjangoFilterBackend
class ProfileViewset(viewsets.ModelViewSet):
model = Profile
serializer_class = UserProfileSerializer
queryset = Profile.objects.all()
filter_backends = [DjangoFilterBackend]
filterset_fields = ['user']

Please add null=True if you want to insert null value.This is my suggestion
class Profile(models.Model):
user = models.OneToOneField(User,null=True,on_delete = models.CASCADE)
bio = models.CharField(max_length=140)
image = models.ImageField(default='default.jpg',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username}'

Related

CustomAccounManager.create_user() missing 1 required positional argument: 'email'

I am trying creating a custom user model in django - which I am using as a backend. On django admin I can create users without issue. My problem arises when I try to register a new account via postman.
In postman I have the email field filled out in the body, yet I still get the error missing 1 required positional argument: 'email'.
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.utils.translation import gettext_lazy as _
class CustomAccounManager(BaseUserManager):
def create_superuser(self, email, username, password, **other_fields):
other_fields.setdefault('is_staff', True)
other_fields.setdefault('is_superuser', True)
other_fields.setdefault('is_active', True)
return self.create_user(self, email, username, password, **other_fields)
def create_user(self, email, username, password, **other_fields):
if not email:
raise ValueError(_('You must provide an email address'))
email = self.normalize_email(email)
user = self.model(email=email, username=username, **other_fields)
user.set_password(password)
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
username = models.CharField(max_length=150, unique = True)
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = CustomAccounManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.username
serializers.py
from rest_framework import serializers
from rest_framework.authtoken.models import Token
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password')
extra_kwargs = {'password': {'write_only': True, 'required': False}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
return user
views.py
from rest_framework import viewsets
from django.shortcuts import render
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset =User.objects.all()
serializer_class = UserSerializer
Any help is appreciated!
This is because you are making USERNAME_FIELD = 'email' in your custom user model, so you have to set USERNAME_FIELD = 'username' and in the email field, set
email = models.EmailField(_('email address'), null=True, blank=True)
but if you need the USERNAME_FIELD = 'email' you have to send it with other data, it's based on your case.

Can not use UserAdmin fildsets with cutom user model

I tried to customize Django User,which worked fine but I lost things like user_permissions.
I don't have user permissions window from which I can give permissions like "can add Product,Can delete cart" etc.
I tried this:
from django.contrib.auth.admin import UserAdmin
fieldsets = UserAdmin.fieldsets + ('Custom fields set', {'fields': ('email', 'staff')}),
and
UserAdmin.fieldsets += ('Custom fields set', {'fields': ('email', 'staff')}),
but these didn't worked for me.
If I try to add 'user_permissions' to fieldsets I get error
" Unknown field 'user_permissions' specified'".
Do I need to define user_permissions fields?
class UserManager(BaseUserManager):
def create_user(self,email,password=None,is_active=True,is_staff=False,is_admin=False):
if not email:
raise ValueError("Users must have email")
if not password:
raise ValueError("Users must have password")
user_obj = self.model(
email = self.normalize_email(email)
)
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.active = is_active
user_obj.set_password(password) #inbuild hashing
user_obj.save(using = self._db)
return user_obj
def create_staffuser(self,email,password=None):
user = self.create_user(email,password=password,is_staff=True)
return user
def create_superuser(self,email,password=None):
user = self.create_user(email,password=password,is_staff=True,is_admin=True)
return user
class User(AbstractBaseUser):
email = models.EmailField(unique=True,max_length=255)
# full_name= models.CharField(max_length=100)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
timestamp= models.DateTimeField(auto_now_add=True)
# confirmed= models.BooleanField(default=False) #confirmed email?
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def has_perm(self,perm,obj=None):
return True
def has_module_perms(self,app_label):
return True
This is how my admin looks currently.
You have to use PermissionsMixin class while creating the custom user model
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
# your fields

DJANGO + JWT TOKEN AUTHENTICATION

So I was trying to build a backend for my Android application. I was trying to apply a login procedure that works with JWT Token
This is what I have done :
I have made a custom User model.
Customize my superuser to take phone number and password, instead of username and password
I have successfully created superuser and store it in my database (using postgreSQL).
I have also customize my token claims and response as seen in my serializers.py of class LoginSerializer.
However, I encounter some problem after what I did :
Right now, after customizing my user model, I was not able to login to Django administration with my new custom made User model, even though I have succesfully created a superuser.
I still can't get the token even after I have made a customization for my token claims, with the success superuser account I just created.
Here are some of the error message :
Here are the some of the files attatched below :
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser,BaseUserManager
from django.utils.translation import ugettext_lazy as _
from phone_field import PhoneField
class RegisterUserManager(BaseUserManager):
def create_user(self, phone_number,password):
if not phone_number:
raise ValueError('The phone number must be set')
user = self.model(
phone_number=phone_number,
password = password,)
user.save(using = self._db)
return user
def create_superuser(self,phone_number,password, **extra_fields):
user = self.create_user(
phone_number,
password = password
)
user.is_admin = True
user.save(using= self._db)
return user
class RegisterUser(AbstractBaseUser):
first_name = models.CharField(name = 'first_name',max_length=255,default = '')
last_name = models.CharField(name='last_name', max_length=255,default = '')
email = models.EmailField(name='email', max_length = 255)
phone_number = PhoneField(name='phone_number',unique=True)
birthday = models.DateField(name ='birthday',null= True)
nickname = models.CharField(max_length=100,name = 'nickname')
is_active = models.BooleanField(default = True)
is_admin = models.BooleanField(default= False)
last_login = models.DateTimeField(auto_now= True)
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = []
objects = RegisterUserManager()
def __str__(self):
return self.phone_number
def has_perm(self, perm, obj = None):
return True
def has_module_perms(self,perm,obj = None):
return True
#property
def is_staff(self):
return self.is_admin
views.py
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from rest_framework.parsers import JSONParser
from restaccount.models import RegisterUser
# Login
from restaccount.serializers import RegisterSerializers,LoginSerializer
# LoginSerializers
from django.views.decorators.csrf import csrf_exempt
from rest_framework.generics import CreateAPIView
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.permissions import (AllowAny,IsAuthenticated)
# from rest_framework.generics import CreateAPIView
class RegisterView(CreateAPIView):
permission_classes = (AllowAny,)
serializer_class = RegisterSerializers
queryset = RegisterUser.objects.all()
class LoginView(TokenObtainPairView):
serializer_class = LoginSerializer
serializers.py
from rest_framework.serializers import (ModelSerializer,ValidationError)
from restaccount.models import RegisterUser
# Login
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
class RegisterSerializers(ModelSerializer):
class Meta:
model = RegisterUser
fields =['id',
'first_name',
'last_name',
'email',
'password',
'phone_number',
'nickname',
'birthday',
]
def create(self,validated_data):
first_name = validated_data['first_name']
last_name = validated_data['last_name']
email = validated_data['email']
password = validated_data['password']
phone_number = validated_data['phone_number']
nickname = validated_data['nickname']
birthday = validated_data['birthday']
user_obj = RegisterUser(
first_name = first_name,
last_name = last_name,
email = email,
password = password,
phone_number = phone_number,
nickname = nickname,
birthday = birthday,
)
user_obj.save()
return user_obj
def update(self, instance,validated_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.password = validated_data.get('password', instance.password)
instance.phone_number = validated_data.get('phone_number', instance.phone_number)
instance.nickname = validated_data.get('nickname', instance.nicknames)
instance.birthday = validated_data.get('birthday',instance.birthday)
instance.save()
return instance
def validate(self,data):
return data
def validate_phone_number(self,value):
phone_number = value
user_qs = RegisterUser.objects.filter(phone_number = phone_number)
if user_qs.exists():
raise ValidationError("This phone number is registered")
return value
class LoginSerializer(TokenObtainPairSerializer):
#classmethod
def get_token(cls,user):
token = super().get_token(user)
token['phone_number'] = user.phone_number
token['password'] = user.password
return token
def validate(self,attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
data['phone_number'] = self.user.phone_number
return data
Turns out that the password field in the model have to be hashed such that
user.set_password(password). This is also the same case, if you want to create a user from the API endpoint. You have to store the hashed password in your database.
However, I don't know why this is the behaviour.

I cant pass all vaues from extra feilds in django Rest allauth framework for custom user model

I created Django custom user model and added restframework to it. Custom User fields are fname, lname, email,username,password,phone ,gender,acctype.
when I register user through the Django restframework, it only takes username,email and password and other field are become empty. what is the problem
my models.py file
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager,User
# Create your models here.
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female')
)
class AccountManager(BaseUserManager):
def create_user(self, email, username, phone, gender, password=None, **extrafields):
if not email:
raise ValueError("email is needed")
if not username:
raise ValueError("username is needed")
if not phone:
raise ValueError("Phone is needed")
if not gender:
raise ValueError("gender is needed")
user= self.model(
email=self.normalize_email(email),
username=username,
phone=phone,
gender=gender,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email,username,phone,gender,password,**extrafields):
user=self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
phone=phone,
gender=gender,
)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
ACCTYPE = (
('Student', 'Student'),
('Staff', 'Staff')
)
fname=models.CharField(verbose_name='fname', max_length=30)
lname=models.CharField(verbose_name='lname', max_length=30)
email = models.EmailField(verbose_name='E-mail', max_length=30, unique=True)
username = models.CharField(verbose_name='Username', max_length=30, unique=True)
last_login = models.DateTimeField(verbose_name='Last Login', auto_now=True)
phone = models.CharField(verbose_name='Phone', max_length=10)
gender = models.CharField(choices=GENDER_CHOICES, max_length=128)
acctype = models.CharField(max_length=16, choices=ACCTYPE)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_verified = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS=['email', 'phone', 'gender']
objects=AccountManager()
def __str__(self):
return self.username
def has_perm(self,perm,obj=None):
return self.is_admin
def has_module_perms(self, app_lebel):
return True
serializer.py
from rest_framework import serializers
from rest_auth.registration.serializers import RegisterSerializer
from accounts.models import Account
from rest_auth.registration.serializers import RegisterSerializer
class CustomRegisterSerializer(RegisterSerializer):
fname = serializers.CharField(required=True)
lname = serializers.CharField(required=True)
username=serializers.CharField(required=True)
email = serializers.EmailField(required=True)
password1 = serializers.CharField(write_only=True)
phone=serializers.CharField(required=True)
gender=serializers.CharField(required=True)
acctype=serializers.CharField(required=True)
def get_cleaned_data(self):
super(CustomRegisterSerializer, self).get_cleaned_data()
return {
'password1': self.validated_data.get('password1', ''),
'email': self.validated_data.get('email', ''),
'username': self.validated_data.get('username', ''),
'fname': self.validated_data.get('fname', ''),
'lname': self.validated_data.get('lname', ''),
'phone': self.validated_data.get('phone', ''),
'acctype': self.validated_data.get('acctype', ''),
'gender': self.validated_data.get('gender', ''),
}
class CustomUserDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('pk','email','fname','lname','username','phone','gender','acctype')
read_only_fields = ('email','acctype','fname','lname')
views.py
from django.shortcuts import render
from rest_framework import generics
from rest_auth.registration.views import RegisterView
from .models import Account
# Create your views here.
class CustomRegisterView(RegisterView):
queryset = Account.objects.all()
Django-allauth doesn't allow saving custom fields by default
To solve this problem I refined a save function inside CustomRegisterSerializer and simply assign the custom field values. Then saved it using user.save()
def save(self, request):
adapter = get_adapter()
user = adapter.new_user(request)
self.cleaned_data = self.get_cleaned_data()
adapter.save_user(request, user, self)
setup_user_email(request, user, [])
user.fname=self.cleaned_data.get('fname')
user.lname=self.cleaned_data.get('lname')
user.phone=self.cleaned_data.get('phone')
user.acctype=self.cleaned_data.get('acctype')
user.gender=self.cleaned_data.get('gender')
user.save()
return user
serializer.py
from rest_framework import serializers
from accounts.models import Account
class CustomRegisterSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = '__all__'
views.py
from rest_framework import viewsets
from .models import Account
from .serializer import CustomRegisterSerializer # import serializer as your path defined
class CustomRegisterView(viewsets.ModelViewSet):
serializer_class = CustomRegisterSerializer
queryset = Account.objects.all()

Django drf simple-jwt authentication"detail": "No active account found with the given credentials"

I am implementing user authentication with django-rest_framework_simple-jwt with custom user,
My models.py:
class UserManager(BaseUserManager):
def create_user(self, email, username, password, alias=None):
user = self.model(
email = self.normalize_email(email),
username = username,)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, username, password):
self.create_user(email, username, password)
user.is_staff()
user.is_superuser = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(null=False, unique=True)
username = models.CharField(max_length=25, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username",]
So I am implementing restframework simple-jwt authentication,my settings .py is as follows as:
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
]}
my urls.py:
urlpatterns = [
url(r'^api/token/$', TokenObtainPairView.as_view(), name='token_obtain_pair'),
url(r'^api/token/refresh/$', TokenRefreshView.as_view(), name='token_refresh'),]
on login process, it returns error that "detail": "No active account found with the given credentials" all my users were active. I have no clue to sort this out, I need help.Thanks in advance.
Ensure your password is being hashed before it is stored in your db. I ran into the same problem and discovered my passwords were being stored in plain text. Adding the following to my UserSerializer solved the issue
from django.contrib.auth.hashers import make_password
def validate_password(self, value: str) -> str:
"""
Hash value passed by user.
:param value: password of a user
:return: a hashed version of the password
"""
return make_password(value)
Either you did not create a superuser for your Django application or you are provided the wrong credentials for authentication
Did you remember to set in settings:
AUTH_USER_MODEL = 'your_app_name.User'
Also make sure, is_active = True for the user object that you are saving in your serializer, because
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['fullname', 'username', 'email', 'password']
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
# Adding the below line made it work for me.
instance.is_active = True
if password is not None:
# Set password does the hash, so you don't need to call make_password
instance.set_password(password)
instance.save()
return instance
Note ( As per docs )
The login_required decorator does NOT check the is_active flag on a user, but the default AUTHENTICATION_BACKENDS reject inactive users.
It seems my error was being caused by a write_only parameter on my password field
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(
max_length=68, min_length=6, write_only=True)
class Meta:
model = User
fields = ['email', 'username', 'password']
Removed it:
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(
max_length=68, min_length=6)
class Meta:
model = User
fields = ['email', 'username', 'password']
and then it was all sunshine and rainbows after that :-)
try this
from django.contrib.auth.hashers import make_password
class UserManager(BaseUserManager):
def create_user(self, email, username, password, alias=None):
user = self.model(
email = self.normalize_email(email),
username = username,)
user.set_password(make_password(password))
user.save()
return user
def create_superuser(self, email, username, password):
self.create_user(email, username, password)
user.is_staff()
user.is_superuser = True
user.save()
return user
Downgraded manually from PyJWT==2.0.0 to PyJWT==1.7.1 and solved our problem
pip install PyJWT==1.7.1
We are using djangorestframework==3.12.1 and djangorestframework-simplejwt==4.4.0 on our requirements.txt and that gave us automatically the 2.0.0 version dependency.
In my opinion, there is a problem where an email address and username is provided for the serializer, but an email is expected as a username for authentication.
I had the same error too. I also made some kind of custom user and tried to login to get a couple of json web tokens. But I only used email, not username. So what I did in the end and it works for me. Perhaps this example explains something in the place where authentication is done ...
Model and manager like this:
from django.db import models
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import (
AbstractBaseUser,
BaseUserManager
)
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ObjectDoesNotExist
from rest_framework_simplejwt.tokens import RefreshToken
class CustomUserManager(BaseUserManager):
def get_or_create(self, email=None, **kwargs):
allowed_kwargs = ['first_name', 'last_name', 'img', 'about']
if email is not None:
try:
user_obj = super(CustomUserManager, self).get(email=email)
if kwargs:
for k, v in kwargs.items():
setattr(user_obj, k, v)
user_obj.save()
except ObjectDoesNotExist:
email = self.normalize_email(email)
user_obj = self.model(email=email)
password = kwargs.pop('password', None)
if password is not None:
user_obj.set_password(password)
if kwargs:
for k, v in kwargs.items():
if k in allowed_kwargs:
setattr(user_obj, k, v)
user_obj.save()
else:
return False
return user_obj
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), null=True, unique=True)
first_name = models.CharField(max_length=150, null=True, blank=True)
last_name = models.CharField(max_length=150, null=True, blank=True)
img = models.URLField(null=True, blank=True)
about = models.TextField(_('about'), max_length=500, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def __str__(self):
return f'<CustomUser(id={self.id} - email={self.email})>'
class Meta:
ordering = ['-created_at']
#property
def full_name(self):
if hasattr(self, 'first_name') and hasattr(self, 'last_name'):
return f'{self.first_name} {self.last_name}'
return 'No fullname'
#property
def jwt_tokens(self):
refresh = RefreshToken.for_user(self)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
Customizing token serializer:
from django.contrib.auth import authenticate
from django.contrib.auth.models import update_last_login
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers
class CustomTokenSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
email = serializers.EmailField(required=True)
password = serializers.CharField(min_length=8, write_only=True)
def validate(self, email, password):
try:
self.user = CustomUser.objects.get(email=email)
except ObjectDoesNotExist as e:
message = {'error': f'User with email={email} does not exist.'}
return message
check_auth = authenticate(username=email, password=password)
if check_auth is None:
message = {'error':
'The user exists, but the password is incorrect.'}
return message
data = self.user.jwt_tokens
update_last_login(None, self.user)
return data
Urls:
urlpatterns += [
path('login/token/', views.LoginTokenView.as_view(), name='login-token')
]
I faced a similar issue. Turns out that I had not included the password field among the fields in the Writer serializer.
Before I had code like this;
class UserWriterSerializer(serializers.ModelSerializer):
class Meta:
model = AppUser
fields = [
'id',
'username',
'first_name',
'last_name',
'email',
'is_active',
'telephone',
'userType',
'gender',
'registration_date'
]
Then I added the password field to have this;
class UserWriterSerializer(serializers.ModelSerializer):
class Meta:
model = AppUser
fields = [
'id',
'username',
'password',
'first_name',
'last_name',
'email',
'is_active',
'telephone',
'userType',
'gender',
'registration_date'
]
So in summary, some different value was being saved in the database which was not the password I added. Thus having that error, because the password you place as an input is not matching with what is in the database. Make sure that the serializer is correct