Django - 从相关表中获取一个附加字段

Posted

技术标签:

【中文标题】Django - 从相关表中获取一个附加字段【英文标题】:Django - grabbing an additional field from related table 【发布时间】: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 端点时,我希望它也从用户模型返回用户 角色。我该怎么做呢?

【问题讨论】:

【参考方案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',)

【讨论】:

以上是关于Django - 从相关表中获取一个附加字段的主要内容,如果未能解决你的问题,请参考以下文章

应用程序名称附加到 django 中的表名称

Android Room - 带有附加字段的多对多关系

Laravel - 从一个表中获取不存在于另一个表中的记录,并附加了 where 子句

在excel中将数据从外部csv附加到表中

我如何发送 JobId 并在视图上附加值。阿贾克斯

[非常急!!!]excel引用access表中的相关字段