在django

时间:2018-02-24 02:33:01

标签: python django

这是我在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()

这是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

这是我的UserSerializer类

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',
        )

这就是我试图注册用户的观点。

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)

我最终收到以下错误消息,

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

但我当然是移动属性。我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

.mobile.email,...不在Serializer对象上,而是在实例上。 UserSerializer(data=...)返回Serializer个实例。 (不是模型实例)

如果您想保留代码,请执行以下操作:

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

但是这样,你没有利用序列化器。

就个人而言,我会摆脱UserManager。 (顺便提一下,创建经理的最佳方法是继承django.db.models.Queryset,然后继续object = UserQueryset.as_manager()

我会像你一样编写一个序列化器:

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

然后在你看来,你只需要这样做:

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

此外,您可以使用通用API视图,而不是编写完整函数。 (CreateAPIView很可能是你想要的。)

N.B。:一切都是伪代码,我还没有测试过,但解决方案应该是非常相似的delta一些小变化