Monday, 5 April 2021

Serializer not working correctly when trying to incorporate username of user

I have a serializer, I'm trying to add an additional field, from a different model. The goal is to add the username from the user who requested the data.

Here is my serializer, I try to accomplish my goal using the username variable and adding it to fields.

class BucketListSerializer(serializers.ModelSerializer, EagerLoadingMixin):

    stock_count = serializers.SerializerMethodField()
   
    username = serializers.CharField(source='User.username', read_only=True)

        model = Bucket
        fields = ('id','username','category','name','stock_count',
                'stock_list','owner','admin_user',
                'guest_user','about','created','slug',
                'bucket_return', 'bucket_sectors','bucket_pos_neg')

    def get_stock_count(self, obj):
        if obj.stock_count:
            return obj.stock_count
        return 0

There aren't any syntax errors with this serializer, however the username field is not working. There is no data in the dictionary returned with the key username

User model:

class CustomAccountManager(BaseUserManager):

    def create_superuser(self, email, username, first_name, last_name, password, **other_fields):

        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('is_active', True)

        if other_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')

        return self.create_user(email, username, first_name, last_name, password, **other_fields)

    def create_user(self, email, username, first_name, last_name, password, **other_fields):

        if not email:
            raise ValueError(_('You must provide an email address'))

        if not username:
            raise ValueError(_('You must provide a username'))

        if not first_name:
            raise ValueError(_('You must provide your first name'))

        if not last_name:
            raise ValueError(_('You must provide your last name'))
        
        if not password:
            raise ValueError(_('You must provide a valid password'))

        email = self.normalize_email(email)
        user = self.model(email=email, username=username,
                          first_name=first_name, last_name=last_name, password=password, **other_fields)
        user.set_password(password)
        user.save()
        return user


class User(AbstractBaseUser, PermissionsMixin):

    email = CIEmailField(_('email address'), unique=True)
    username = CICharField(max_length=150, unique=True)
    first_name = models.CharField(max_length=150, blank=True)
    last_name = models.CharField(max_length=150, blank=True)
    start_date = models.DateTimeField(default=timezone.now)
    subscribed = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)

    objects = CustomAccountManager()


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', 'first_name', 'last_name','password']

    def __str__(self):
        return self.username

Here is the view used:

class BucketList(generics.ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = BucketListSerializer
    filter_backends = [OwnerOrUserFilterBackend]
    queryset = Bucket.objects.all()

how can I simply add the username of a user to my serializer class above?


EDIT:

Here is my bucket model:


class Bucket(models.Model):

    category_options = (
        ('personal', 'Personal'),
        ('social', 'Social'),
    )


    class BucketObjects(models.Manager):
        def get_queryset(self):
            return super().get_queryset()

    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='buckets')
    admin_user = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='admin_user')
    guest_user = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='guest_user', blank=True)
    category = models.CharField(max_length=30, choices=category_options)
    name = models.CharField(max_length=35)
    created = models.DateTimeField(default=timezone.now, blank=True)
    slug = AutoSlugField(populate_from = "random_string", blank=True) 
    stock_count = models.IntegerField(blank=True, null=True)
    stock_list = ArrayField(models.CharField(max_length=6,null=True),size=30,null=True, blank=True)
    about = models.CharField(max_length=200)

    objects = models.Manager()
    bucketobjects = BucketObjects()

EDIT #2

class BucketListSerializer(serializers.ModelSerializer):
   
    user = serializers.SerializerMethodField('get_user')

    class Meta:
        model = Bucket
        fields = (...'user')


    def getUsername(self, obj):
        user = self.context['request'].user
        return obj.user



from Serializer not working correctly when trying to incorporate username of user

No comments:

Post a Comment