0

This is my customized User Object in django.

class User(AbstractBaseUser, PermissionsMixin):
    mobile = models.CharField(max_length=100, unique=True)
    email = models.EmailField(max_length=255, null=True)
    username = models.CharField(max_length=255, null=True)
    full_name = models.CharField(max_length=255, blank=True, null=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True)

    USERNAME_FIELD = 'mobile'
    REQUIRED_FIELDS = []
    objects = UserManager()

And this is the UserManager,

class UserManager(BaseUserManager):

    def create_user(self, mobile, email=None, username=None, full_name=None, password=None, is_staff=False,
                    is_superuser=False):
        if not mobile:
            raise ValueError("Can't create User without a mobile number!")
        if not password:
            raise ValueError("Can't create User without a password!")
        user = self.model(
            mobile=mobile,
            email=self.normalize_email(email),
            username=username,
            full_name=full_name,
            is_staff=is_staff,
            is_superuser=is_superuser,
        )
        user.set_password(password)
        user.save(self._db)
        return user

This is my UserSerializer Class

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    id = serializers.IntegerField(read_only=True)

    class Meta:
        model = models.User
        fields = (
            'id',
            'mobile',
            'email',
            'username',
            'full_name',
            'password',
        )

And this is the view where I'm trying to register a User.

class RegisterView(views.APIView):
    def post(self, request):

        serialized = UserSerializer(data=request.data)
        if serialized.is_valid():
            user = UserManager().create_user(mobile=serialized.mobile, email=serialized.email, username=serialized.email, full_name=serialized.full_name, password=serialized.password)
            if user:
                return Response(serialized.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serialized.errors, status=status.HTTP_400_BAD_REQUEST)

I end up getting the following error message,

AttributeError at /api/v1/bouncer/register/
'UserSerializer' object has no attribute 'mobile'

But of course I've a mobile attribute. What am I doing wrong here?

1 Answer 1

1

.mobile, .email, ... are not on the Serializer object but on the instance. UserSerializer(data=...) returns a Serializer instance. (not a model instance)

If you want to keep your code the solution is to do:

UserManager().create_user(
    mobile=serialized.validated_data['mobile'],
    email=serialized.validated_data['email'],
    ...

But this way, you're not taking advantage of the serializer.

Personally, I would get rid of the UserManager. (By the way, the best way to create a manager is to inherit from django.db.models.Queryset and then do object = UserQueryset.as_manager())

I would write a serializer, like yours:

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    id = serializers.IntegerField(read_only=True)

    class Meta:
        model = models.User
        fields = (
            'id', 'mobile', 'email', 'username', 'full_name', 'password',
        )

    def create(self, validated_data):
        password = validated_data.pop('password')
        user = super().create(validated_data)
        user.set_password(password)
        return user

Then in your view, you just have to do:

serializer = UserSerializer(data=request.data)
if serializer.is_valid():
    serializer.save()
    return Response(...)
else:
    return Response(...)

Also, instead of writing a full function, you could use a generic API view. (CreateAPIView is most likely what you want.)

N.B.: Everything is pseudocode, I have not tested it, but the solution should be extremely similar delta some small changes

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.