Django中如何重命名select_related后values()查询的字段名?
解决Django关联查询后values()字段重命名的问题
嗨,我正好碰到过类似的情况,来给你说下正确的解决办法~
你提到直接在values()里写键值对会报错,那是因为你用字符串指定关联字段的方式不对——Django会把这种写法当成过滤条件,而不是字段重命名。要实现关联字段的重命名,咱们需要用F()表达式来指向关联模型的字段,或者结合annotate()先给字段起别名,两种方法都能解决你的问题,下面给你具体演示:
先确认下模型结构(方便对应代码)
假设你的模型大概是这样的:
class Userinfo(models.Model): useruid = models.CharField(primary_key=True, max_length=50) username = models.CharField(max_length=50) userstatus = models.IntegerField() class Postinfo(models.Model): postid = models.AutoField(primary_key=True) useruid = models.ForeignKey(Userinfo, on_delete=models.CASCADE) # 其他Postinfo字段...
方法一:直接在values()中使用F()表达式重命名
这是最简洁的方式,Django 1.8+(包括你用的2.0.2)都支持。只需要在values()里用关键字参数,值为F('关联字段路径'):
from django.db.models import F # 执行查询 result = Postinfo.objects.select_related('useruid').values( # 先写Postinfo自己的字段,比如postid 'postid', # 然后用F()重命名关联字段 username=F('useruid__username'), userstatus=F('useruid__userstatus'), useruid=F('useruid__useruid') )
执行后,返回的每个字典里的字段名就是你想要的username、userstatus、useruid,而不是带双下划线的长字段名。
方法二:先用annotate()给字段起别名,再用values()提取
如果你觉得第一种写法不够直观,也可以先通过annotate()给关联字段添加别名,再用values()提取这些别名:
from django.db.models import F result = Postinfo.objects.select_related('useruid').annotate( username=F('useruid__username'), userstatus=F('useruid__userstatus'), useruid=F('useruid__useruid') ).values('postid', 'username', 'userstatus', 'useruid')
这种方式和第一种效果完全一样,只是把重命名的逻辑放到了annotate()步骤里,适合需要对字段做更多处理的场景。
关键注意点
- 一定要导入
F表达式:from django.db.models import F,不然会报错。 select_related('useruid')不能丢,它会让Django一次性关联查询Userinfo表,避免N+1查询的性能问题。
这样处理后,你就能得到字段名简洁的查询结果啦~
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

