Reputation: 3605
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?
Upvotes: 0
Views: 174
Reputation: 391
.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
Upvotes: 1