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'.
它是user
和role
之间的两个下划线 - 这就是您访问相关对象的属性的方式,两个下划线。在您的评论中,您只有一个
我应该澄清一下 - 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 - 从相关表中获取一个附加字段的主要内容,如果未能解决你的问题,请参考以下文章