Python 尝试合并用户的用户名时序列化程序无法正常工作

Python 尝试合并用户的用户名时序列化程序无法正常工作,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有一个序列化程序,我正在尝试添加一个来自不同模型的附加字段。目标是添加请求数据的用户的用户名 这是我的序列化程序,我尝试使用username变量并将其添加到字段中来实现我的目标 class BucketListSerializer(serializers.ModelSerializer, EagerLoadingMixin): stock_count = serializers.SerializerMethodField() username = serializer

我有一个序列化程序,我正在尝试添加一个来自不同模型的附加字段。目标是添加请求数据的用户的用户名

这是我的序列化程序,我尝试使用
username
变量并将其添加到字段中来实现我的目标

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
此序列化程序没有任何语法错误,但是
username
字段不起作用。字典中没有使用键
用户名返回的数据

用户模型:

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
以下是使用的视图:

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

如何简单地将用户的用户名添加到上面的序列化程序类中


编辑:

这是我的水桶模型:


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()

编辑#2

正确的答案应该是

class BucketListSerializer(serializers.ModelSerializer, EagerLoadingMixin):
    ...
    username = serializers.CharField(source='owner.username', read_only=True)
    ...

我认为您可以在序列化程序中使用上下文:

user = self.context['request'].user
user = serializers.SerializerMethodField(read_only=True)

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


def get_user(self, instance):
    user = self.context['request'].user
    return user
因此,如果要显示用户名,可以将用户名创建为SerailizerMethodField,并从请求上下文中获取的用户对象返回用户名

类BucketListSerializer(serializers.ModelSerializer):


这将对您有用。

发布Bucket模型请查看新的发布更新。嗨,panchicore,谢谢您的帮助。但是,当
所有者
不是请求的用户时,它就不起作用了。我正在尝试获取用户提供的请求的用户名。有趣的用例,特别是因为您必须在某个地方设置用户名,因为用户名没有存储在模型上,我会做一个实验,为Bucket模型创建一个属性,因此,您可以将源映射到序列化器字段,以便设置request.user.username值,然后覆盖ListAPIView(我认为是get_对象方法)并在那里设置请求的用户用户名。请查看我的新更新。我已经试着实现了你推荐的方法,但我做得不对。“用户”是你的对象,使用调试器并检查它是否返回任何东西。若我并没有弄错,那个么用户应该是一个对象,你们必须返回user.username。在调试器模式下运行代码并在返回时添加断点不太确定我是否理解您的意思,您是否可以演示给我看?您可以参考以下内容:在pycharm中使用调试器(不确定,但可能也可以在其他编辑器中执行),了解您的代码正在执行的操作非常有用。我已经更新了我的回复,你可以试试。
user = serializers.SerializerMethodField(read_only=True)

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


def get_user(self, instance):
    user = self.context['request'].user
    return user
username = serializers.SerializerMethodField('_user')

def _user(self, obj):
    request = self.context.get('request', None)
    if request and request.user:
        return request.user.username
    return ''