Django Rest Framework AttributeError 'CustomUser' object has no attribute 'user'

Viewed 699

I have different types of users. That's why, each user type should have own profile details. So I am trying to code API for these profiles. However, I couldn't resolve this error. I am following an example from a course. My code is completely similar as this example. I don't understand where am I going wrong.

It seems that I am making a mistake in reconciling the related models. I checked the aliases and tried over and over to solve it. I tried many alises to solve it but i couldn't be successful each time.

Error message

AttributeError at /api/account/child-profile-update
Got AttributeError when attempting to get a value for field `user` on serializer `ChildProfileSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `CustomUser` instance.
Original exception text was: 'CustomUser' object has no attribute 'user'.

Custom User Model

class CustomUser(AbstractUser):
    GENDER_CHOICES = (
        (1, AccountStrings.CustomUserStrings.gender_choice_male),
        (2, AccountStrings.CustomUserStrings.gender_choice_female),
        (3, AccountStrings.CustomUserStrings.gender_choice_other),
    )

    USER_TYPE_CHOICES = (
        (1, AccountStrings.CustomUserStrings.user_type_choice_default),
        (2, AccountStrings.CustomUserStrings.user_type_choice_child),
        (3, AccountStrings.CustomUserStrings.user_type_choice_parent),
        (4, AccountStrings.CustomUserStrings.user_type_choice_instructor),
    )
    objects = CustomUserManager()
    email = models.EmailField(max_length=255,
                              unique=True,
                              null=False,
                              blank=False)
    identity_number = models.CharField(
        max_length=11,
        unique=True,
        verbose_name=AccountStrings.CustomUserStrings.
        identity_number_verbose_name)
    birth_date = models.DateField(
        null=True,
        blank=True,
        verbose_name=AccountStrings.CustomUserStrings.birth_date_verbose_name)
    gender = models.PositiveSmallIntegerField(
        choices=GENDER_CHOICES,
        default=1,
        verbose_name=AccountStrings.CustomUserStrings.gender_verbose_name)
    user_type = models.PositiveSmallIntegerField(
        choices=USER_TYPE_CHOICES,
        default=1,
        verbose_name=AccountStrings.CustomUserStrings.user_type_verbose_name)

Child Profile Model

class ChildProfile(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        primary_key=True,
        verbose_name=AccountStrings.ChildProfileStrings.user_verbose_name,
        related_name="user_child")
    city = models.ForeignKey(
        City,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=AccountStrings.ChildProfileStrings.city_verbose_name,
        related_name="city_child_profiles")
    hobbies = models.CharField(
        max_length=500,
        null=True,
        blank=True,
        verbose_name=AccountStrings.ChildProfileStrings.hobbies_verbose_name)

   

Child Profile Serializers

from rest_framework.serializers import ModelSerializer
from account.models import ChildProfile
from django.contrib.auth import get_user_model

User = get_user_model()


class ChildProfileSerializer(ModelSerializer):
    class Meta:
        model = ChildProfile
        fields = "__all__"

class UserChildSerializer(ModelSerializer):
    childprofile = ChildProfileSerializer()

    class Meta:
        model = User
        fields = ["id", "first_name", "last_name", "email", "identity_number", "gender", "birth_date", "childprofile"]

Views

from django.contrib.auth import get_user_model

User = get_user_model()

class ChildProfileUpdateAPIView(RetrieveUpdateAPIView):
    queryset = User.objects.all()
    serializer_class = ChildProfileSerializer

    def get_object(self):
        queryset = self.get_queryset()
        obj = User.objects.get(id = self.request.user.id)
        return obj
1 Answers

The problem is caused by ChildProfileUpdateAPIView.get_object returning a User/CustomUser instance when it should most probably be a ChildProfile instance.

Essentially, you are using a User/CustomUser against ChildProfileSerializer which will fail with the error you see.

To fix this, try:

def get_object(self):
    obj = ChildProfile.objects.get(user=self.request.user)
    return obj
Related