#DRF error in Token Auth:{'invalid': Invalid data. Expected a dictionary, but got {datatype}.}

25 messages · Page 1 of 1 (latest)

mental hedge
#

My model is following

class CustomUserManager(BaseUserManager):
    """This class base function for creating a Custom User model."""

    def create_user(self, email, username, password=None):
        if not email:
            raise ValueError("The Email field must be set")
        if not username:
            raise ValueError("User must have a unique username.")
        email = self.normalize_email(email)
        user = self.model(email=email, username=username)
        user.set_password(password)
        user.save(using=self._db)
        return user

class CustomUser(AbstractBaseUser, PermissionsMixin):
    """This class defines fields for CustomUser model."""

    email = models.EmailField(unique=True)
    username = models.CharField(verbose_name="username", max_length=255, unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    date_joined = models.DateTimeField(default=timezone.now)
    is_active = models.BooleanField(default=True)

    # Add your custom fields here as needed

    objects = CustomUserManager()

    USERNAME_FIELD = "username"
    EMAIL_FIELD = "email"
    REQUIRED_FIELDS = ["email"]

    def __str__(self) -> str:
        return self.username

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

    def has_module_perms(self, app_label):
        return True

My views.py file is following

    serializer_class = CustomUserLoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data, context={"request": request}
        )
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data["user"]
        token, created = Token.objects.get_or_create(user=user.pk)
        return Response(
            {"token": token.key, "user_email": user.email, "username": user.username},
            status=status.HTTP_200_OK,
        )
pseudo sparrow
#

What datatype is the view getting?

mental hedge
#

JSON from postman

    "username": "test",
    "password": "test123"
}

The response

    "username": [
        "custom user with this username already exists."
    ]
}```
pseudo sparrow
#

That's a different error from your thread title though

mental hedge
#

The thread title is from the debugger

#

Here is the error from the debugger

self.serializer_class.default_error_messages = {dict: 1} {'invalid': Invalid data. Expected a dictionary, but got {datatype}.}
 'invalid' = {__proxy__: 56} Invalid data. Expected a dictionary, but got {datatype}.
 __len__ = {int} 1
pseudo sparrow
#

I'm not sure that's an error

pseudo sparrow
mental hedge
#

Hmm good point. Let me check again

pseudo sparrow
#

Is it possible the wrong view is handling this request?

mental hedge
#

Hmm, nope urls.py is solid

Here is my serializer though

class CustomUserLoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ["username", "password"]
        extra_kwargs = {"password": {"write_only": True}}
#

Is my code correct?

pseudo sparrow
mental hedge
pseudo sparrow
#

What's happening is that your custom serializer is validating the username and password as if it's going to be used to insert a new record. This is because there's no user instance passed along with it so it thinks you want to create a user. When is_valid is called it checks for duplicate usernames and finds the current user

pseudo sparrow
#

I'm also betting that you could just drop the serializer_class attribute from the class definition and it'll work

mental hedge
mental hedge
pseudo sparrow
#

Well authenticate does a db lookup

mental hedge
#

@pseudo sparrow You were right about the Serializer. Got a new error

'username'```
mental hedge
#

This error is still open but I am probably not going to use Token Auth now.

pseudo sparrow
#

Gotcha. Since you never included details I figured you didn't want help

mental hedge
#

@pseudo sparrow My code is literally a copy of the ObtainTokenAuth class but man it just won't work