如何在Django中获取含AUTH_USER_MODEL用户名的Additional模型QuerySet?
问题
我定义了通过OneToOneField关联默认AUTH_USER_MODEL的Additional模型,代码如下:
class Additional(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) vut_id = models.IntegerField() edit_right = models.BooleanField(default = False) add_access_right = models.BooleanField(default = False)
我需要获取包含AUTH_USER_MODEL中username字段的Additional模型QuerySet。使用Additional.objects.select_related('user').all()仅返回用户ID,返回格式如下:
{ "model": "authentication.additional", "pk": 13, "fields": { "user": 15, "vut_id": 123456, "edit_right": false, "add_access_right": false } }
期望的返回格式为:
{ "model": "authentication.additional", "pk": 13, "fields": { "username": "user1", "vut_id": 123456, "edit_right": false, "add_access_right": false } }
请问该如何实现此需求?
解决方案
方法1:用annotate注入username字段到QuerySet
通过annotate结合F表达式,直接将关联用户的username字段添加到Additional的查询结果中,后续可直接访问该字段:
from django.db.models import F # 构造包含username的QuerySet additional_list = Additional.objects.select_related('user').annotate( username=F('user__username') ).all()
每个Additional实例会新增username属性,对应关联用户的用户名。
方法2:在DRF序列化器中自定义字段(适用于API场景)
如果是用Django REST Framework返回接口数据,在序列化器中直接映射user.username为username字段:
from rest_framework import serializers from .models import Additional class AdditionalSerializer(serializers.ModelSerializer): # 从关联的user对象中获取username username = serializers.CharField(source='user.username') class Meta: model = Additional fields = ['username', 'vut_id', 'edit_right', 'add_access_right']
使用该序列化器处理QuerySet时,返回结果会自动包含username字段。
方法3:给模型添加@property属性
在Additional模型中定义一个属性方法,直接返回关联用户的用户名:
class Additional(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) vut_id = models.IntegerField() edit_right = models.BooleanField(default = False) add_access_right = models.BooleanField(default = False) @property def username(self): return self.user.username
这样每个Additional实例都可以通过instance.username直接获取用户名,但注意要提前用select_related('user')避免额外的数据库查询。
内容的提问来源于stack exchange,提问作者Noobie
相关产品推荐
相关产品推荐

