Home > Blockchain >  Getting "AuthToken.user" must be a "User" instance. in django-rest-knox
Getting "AuthToken.user" must be a "User" instance. in django-rest-knox

Time:12-17

I am creating a login method using Django-rest-Knox. I have created a custom user in app using AbstractBaseUser.

This is my views.py

class LoginView(GenericAPIView):
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)  # Load request body to serializer
        serializer.is_valid(raise_exception=True)  # Validate data in serializer and raise an error if one is found

        user = serializer.validated_data  # Get the validated data from the serializer
        token = AuthToken.objects.create(user)[1]  # Create an Authentication Token for the user

        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,  # Get serialized User data
            "token": token
        })

Serializer.py

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    # class Meta:
    #     model = User
    #     fields = ('username', 'password')
    def Validate(self, data):
        user = authenticate(**data)
        if user:
            return user
        raise serializers.ValidationError("Incorrect Credentials")

This is my custom user model

class User(AbstractBaseUser):
    _id = models.AutoField
    email = models.EmailField(verbose_name='email', max_length=255, unique=True)
    username = models.CharField(verbose_name='username', max_length = 100, unique=True)
    name = models.CharField(max_length = 100)
    date_joined = models.DateTimeField(verbose_name="date-joined", auto_now_add=True)
    last_login = models.DateTimeField(verbose_name="last-login", auto_now=True)
    category = models.CharField(max_length=50, default= "teacher")
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_teacher = models.BooleanField(default=False)
    is_parent = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email',]

    objects = UserManager()
    
    def __str__(self):
        # return self.email
        return self.username

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

I am getting an Value error when submitting login as Cannot assign "OrderedDict([('username', 'api_test'), ('password', 'test@123')])": "AuthToken.user" must be a "User" instance.

I think somewhere Django/Knox is not able to get user and user.is_active in my LoginSerializer. I have initiated my user model from initial migrations.

Any help to resolve this issue would be great. Thanks.

CodePudding user response:

In this part of your code :

 return Response({
        "user": UserSerializer(user, context=self.get_serializer_context()).data,  # Get serialized User data
        "token": token
    })

You need to replace the token by an instance of the user on which this token belong so for example :

 return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,  # Get serialized User data
            "token": User.objects.get(token=token)
        })
  • Related