You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Django中获取包含所有抽奖获奖者的Employee类型QuerySet

获取PrizeDraw获奖者的Employee QuerySet解决方案

嘿,我明白你的问题了——你想要的是真正的Employee实例组成的QuerySet,而不是字典集合对吧?之前用values()确实会返回字典,这不符合后续代码的需求,我给你几个可行的方案,其中最推荐的是第一种,简洁又高效:

方法一:利用Django反向关联直接查询(推荐)

Django的ForeignKey会自动给关联的Employee模型添加一个反向关联管理器,默认名称是prizedraw_set(规则是关联模型名小写加_set)。我们可以直接用这个反向关联来过滤出有获奖记录的员工:

def get_queryset(self):
    # 过滤出存在获奖记录的Employee,distinct()避免同一员工多次获奖重复出现
    return Employee.objects.filter(prizedraw__isnull=False).distinct()

如果你的场景需要保留重复的获奖记录(比如要统计每个员工获奖次数),直接去掉.distinct()就可以了。这种方法只需要一次SQL查询,性能最优,代码也最简洁。

方法二:从PrizeDraw出发,通过主键关联查询

如果你更习惯从PrizeDraw模型入手,可以先提取所有获奖者的主键,再用这个主键列表查询Employee

def get_queryset(self):
    # 先获取所有非空获奖者的主键
    winner_pks = PrizeDraw.objects.exclude(winner__isnull=True).values_list('winner__pk', flat=True)
    # 通过主键列表查询对应的Employee,同样可以加distinct()去重
    return Employee.objects.filter(pk__in=winner_pks).distinct()

这种方法会生成两次SQL查询,但比直接遍历PrizeDraw实例再提取员工要高效,因为values_list是在数据库层面完成的主键提取。

方法三:关联查询后提取实例(不推荐)

还有一种方式是先给PrizeDrawselect_related关联查询,再提取对应的winner实例,但这种方法需要遍历QuerySet,性能不如前两种:

def get_queryset(self):
    # 先查询所有有获奖者的PrizeDraw,并关联查询对应的Employee
    prize_draws = PrizeDraw.objects.exclude(winner__isnull=True).select_related('winner')
    # 通过主键过滤得到Employee QuerySet
    return Employee.objects.filter(pk__in=[pd.winner.pk for pd in prize_draws])

这种方法不推荐,因为遍历QuerySet会把数据加载到内存,数据量大的时候性能会很差。


内容的提问来源于stack exchange,提问作者Yellow

火山引擎 最新活动