【问题标题】:Django - grabbing an additional field from related tableDjango - 从相关表中获取一个附加字段
【发布时间】:2020-04-07 05:25:26
【问题描述】:

我有以下型号:

class User(AbstractBaseUser, PermissionsMixin):
    SUPERVISOR = 1
    REVIEWER = 2
    VERIFIER = 3
    READ_ONLY = 4
    USER_TYPE = [
        (SUPERVISOR, 'Supervisor'),
        (REVIEWER, 'Reviewer'),
        (VERIFIER, 'Verifier'),
        (READ_ONLY, 'Read Only'),
    ]
    email = models.EmailField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    phone = models.CharField(max_length=50, null=True)
    role = models.IntegerField(
        choices=USER_TYPE,
        default=READ_ONLY
    )
    is_active = models.BooleanField(default=True)


class Comment(models.Model):
    text = models.TextField()
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.PROTECT
    )

查看:

class CommentViewSet(BaseCertViewSet):
    queryset = Comment.objects.all()
    serializer_class = serializers.CommentSerializer

序列化器:

class CommentSerializer(serializers.ModelSerializer):
    user = serializers.SlugRelatedField(
        read_only=True,
        slug_field='name'
    )


    class Meta:
        model = Comment
        fields = ('id', 'text', 'user',)
        read_only_fields = ('id',)

我的问题:当我点击评论 API 端点时,我希望它也从用户模型返回用户 角色。我该怎么做呢?

【问题讨论】:

    标签: django django-rest-framework django-serializer


    【解决方案1】:

    我相信你可以使用QuerySet.annotation

    编辑:F 来自 django.db.models,所以你也必须导入它。

    queryset = Comment.objects.annotate(user_role=F("user__role")) 在你的CommentViewSet

    编辑: 为了让序列化程序识别您尝试添加到QuerySet 的字段,您还必须像这样在序列化程序上定义该字段:

    class CommentSerializer(serializers.ModelSerializer):
        user = serializers.SlugRelatedField(
            read_only=True,
            slug_field='name'
        )
    
        # add line below to your code
        user_role = IntegerField()
    
        class Meta:
            model = Comment
            # you have to add it to the list of fields as well
            fields = ('id', 'text', 'user', 'user_role')
            read_only_fields = ('id',)
    

    【讨论】:

    • 谢谢。我得到:django.core.exceptions.ImproperlyConfigured: Field name 'user_role' is not valid for model 'Comment'.
    • 它是userrole 之间的两个下划线 - 这就是您访问相关对象的属性的方式,两个下划线。在您的评论中,您只有一个
    • 我应该澄清一下 - F('user__role') 中有两个您使用两个下划线
    • 这只是 django 返回的错误,我确实完全按照您的建议使用双下划线。在序列化程序方面我需要做些什么吗?
    • 啊 - 我明白你现在在说什么了
    【解决方案2】:

    对我有用的解决方案(不确定它是不是最优雅的,很高兴改用更好的方法):

    class CommentSerializer(serializers.ModelSerializer):
        """Serializer for Comment object"""
    
        user = serializers.SlugRelatedField(
            read_only=True,
            slug_field='name'
        )
    
        role = serializers.SerializerMethodField()
    
        def get_role(self, obj):
            user = obj.user_id
            role = User.objects.only('id').get(
                id=user).role
            return role
    
        class Meta:
            model = Comment
            fields = ('id', 'value', 'text', 'user', 'role',
                      'date_created', 'date_updated')
            read_only_fields = ('id',)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2020-11-26
      相关资源
      最近更新 更多