DjangoRestFramework序列化自定义用户模型

时间:2013-05-15 14:02:48

标签: django serialization unique django-rest-framework

我已经定义了一个自定义用户模型类,如下所示

class LabUserManager(BaseUserManager):
    """
    A new user manager for both standard and administrative users
    """

    def create_user(
            self, 
            email,
            first_name,
            last_name,
            university,
            job_title,
            bio,
            password=None
    ):
        """
        Creates a standard user with no administrative privledges
        """
        if not email:
            raise ValueError('Users must provide an email')

        if not first_name:
            raise ValueError('Users must provide a first name')

        if not last_name:
            raise ValueError('Users must provide a last name')

        if not university:
            raise ValueError('Users must provide an email address')

        # Note: a biography and job_title are not required
        user.set_password(password)
        user.save(using=self._db)
        return user


    def create_superuser(
            self, 
            email,
            first_name,
            last_name,
            university,
            job_title,
            bio,
            password=None
    ):
        """
        Creates an administrative user
        """    

        user = self.create_user(
            self, 
            email,
            first_name,
            last_name,
            university,
            job_title,
            bio,
            password=None
        )
        user.is_admin = True
        user.save(using=self._db)
        return user                

class LabUser(AbstractBaseUser):
    """
    Model for every user on the site
    The only required fields are:
        email,
        first_name,
        last_name,
        university,
    although, this will be discussed later
    """
    email = models.EmailField(
        verbose_name = 'email address',
        max_length   = 255,
        unique       = True,
        db_index     = True,
    )
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.CharField(max_length=150)
    job_title = models.CharField(max_length = 50)
    bio = models.TextField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)

    objects = LabUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [
        'first_name',
        'last_name',
        'university',
    ]

    @property 
    def is_staff(self):
        return self.is_admin

使用序列化程序

class NewUserSerializer(serializers.Serializer):
    """
    Defines a new user serializer
    """
    pk = serializers.Field()
    email = serializers.EmailField()
    first_name = serializers.CharField(max_length=50)
    last_name = serializers.CharField(max_length=50)
    university = serializers.CharField(max_length=150)
    job_title = serializers.CharField(
        max_length=50,
        required=False
    )
    bio = serializers.CharField(
        widget=widgets.Textarea,
        required=False
    )
    password = serializers.CharField(
        max_length=64,
        widget=widgets.PasswordInput
    )

    def restore_object(self, attrs, instance=None):
        if instance: # Update email university bio or job_title
            user = instance
            user.email = attrs['email']
            user.university = attrs['university']
            user.bio = attrs['bio']
            user.job_title = attrs['job_title']
            user.set_password(attrs.get('password'))
        else:
            user = LabUser(
                email=attrs['email'],
                first_name=attrs['first_name'],
                last_name=attrs['last_name'],
                university=attrs['university'],
                job_title=attrs['job_title'],
                bio=attrs['bio']
                # Check custom user model page for other parameters
            )
            user.set_password(attrs.get('password'))
            user.save()
        return user

使用视图

class NewUser(generics.CreateAPIView):
    serializer_class = NewUserSerializer

但是当我发布一个有新电子邮件地址的新用户时,我收到以下错误

IntegrityError at /users/new/
PRIMARY KEY must be unique
Request Method: POST
Request URL:    http://127.0.0.1:8000/users/new/
Django Version: 1.5.1
Exception Type: IntegrityError
Exception Value:    
PRIMARY KEY must be unique

1 个答案:

答案 0 :(得分:2)

在某些时候,您似乎在创建新对象时提交并处理主键值。这只是一个猜测,但我认为这发生在NewUserSerializer的某处,因为您明确添加了pk字段,该字段不是只读的,并且不强制执行正整数值。我会尝试使用IntegerField代替read_only=True,看看是否能解决问题。

但我强烈建议您使用ModelSerializer。你仍然可以拥有每个字段的自定义小部件,但它也会处理一些比你的实现更简洁的东西。而且你必须编写更少的代码。