简体   繁体   中英

Serializing and Deserialzing User using Djoser Django Rest

I am quiet new to django and i am using djoser to create a user. I have custom user Model and Custom User Serializer. My Custom User is following.

class User(AbstractBaseUser, PermissionsMixin):
    """
    A fully featured User model with admin-compliant permissions that uses
    a full-length email field as the username.

    Email and password are required. Other fields are optional.
    """
    email = models.EmailField(_('email address'), max_length=254, unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    middle_name = models.CharField(_('middle name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    is_staff = models.BooleanField(_('staff status'), default=False,
                                   help_text=_('Designates whether the user can log into this admin '
                                               'site.'))
    is_active = models.BooleanField(_('active'), default=True,
                                    help_text=_('Designates whether this user should be treated as '
                                                'active. Unselect this instead of deleting accounts.'))
    extra_field = models.BooleanField(_('changethis'), default=False,
                                      help_text=_('Describes whether the user is changethis '
                                                  'site.'))
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    username = models.CharField(_('username'), max_length=30, blank=True)

    roles = models.ManyToManyField(Role, related_name='role_user')

    objects = CustomUserManager()

and following is my CustomUserManager()

class CustomUserManager(BaseUserManager):
    def _create_user(self, email, password,
                     is_staff, is_superuser, **extra_fields):
        now = timezone.now()
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email,
                          is_staff=is_staff, is_active=True,
                          is_superuser=is_superuser, last_login=now,
                          date_joined=now, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        return self._create_user(email, password, False, False,
                                 **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        return self._create_user(email, password, True, True,
                                 **extra_fields)

And following is my serializer code.

class RegisterSerializer(serializers.Serializer):
    email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
    first_name = serializers.CharField(required=True)
    middle_name = serializers.CharField(required=False)
    last_name = serializers.CharField(required=True)
    password = serializers.CharField(required=True, write_only=True)
    roles = serializers.ListSerializer(child=serializers.IntegerField())

    # def create(self, validated_data):
    def create(self, validated_data):
        roles_ids = validated_data.pop('roles')
        roles = Role.objects.filter(id__in=roles_ids)
        user = User.objects.create_user(**validated_data)
        user.roles.set(roles)
        return user

Since the Roles objects are already created so i just take a list of ids of roles from request and filter these objects of roles and set them for the respective user. Now the user is being created just fine but when djoser tries to return response using same serializer it throws following exception.

TypeError: int() argument must be a string, a bytes-like object or a number, not 'Role'

because roles are supposed to be list of integers not List of Role Objects. How can i fix it?

Change this

roles = serializers.ListSerializer(child=serializers.IntegerField())

to

roles = serializers.ListField(child=serializers.IntegerField())

Or,

If you want to list all roles then create a new serializer for roles and add it to child like:

roles = serializers.ListSerializer(child=RolesSerializer())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM