You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django prefetch_related过滤失效,预加载关联数据返回非指定用户记录

问题根因

你为Prefetch指定的用户过滤条件没有生效,核心原因是后续调用了.values()方法且通过双下划线inventoryCards__xxx直接读取关联表字段:该操作会触发Django直接对两张表执行SQL JOIN,完全绕过prefetch_related的预加载逻辑,你写的Prefetch过滤规则不会被应用到最终执行的SQL中,自然会返回所有用户的库存数据,出现同卡多条记录的问题。

解决方案

优先推荐放弃直接用values读取关联字段,通过预加载的模型实例手动构造返回数据,示例如下:

sql_int = "CAST((REGEXP_MATCH(number, '\d+'))[1] as INTEGER)"
cards = magic_set_cards.objects.all().exclude(side='b').extra(select={'int': sql_int}) \
    .prefetch_related(Prefetch('inventoryCards', queryset=inventory_cards.objects.filter(user_id=request.user.id))) \
    .order_by('-set_id__releaseDate', 'set_id__name', 'int', 'number')

# 手动构造返回字段
result = []
for card in cards:
    # 预加载的inventoryCards已过滤仅保留当前用户数据,最多存在1条
    user_inventory = card.inventoryCards.first()
    result.append({
        'id': card.id,
        'set_id__code': card.set_id.code,
        'set_id__name': card.set_id.name,
        'set_id__isOnlineOnly': card.set_id.isOnlineOnly,
        'number': card.number,
        'name': card.name,
        'imageUri': card.imageUri,
        'hasNonFoil': card.hasNonFoil,
        'hasFoil': card.hasFoil,
        'inventoryCards__nonfoil': user_inventory.nonfoil if user_inventory else 0,
        'inventoryCards__foil': user_inventory.foil if user_inventory else 0
    })

注意事项

  • 若使用Django REST Framework,可直接在Serializer中读取预加载的关联库存数据,无需手动拼接字典
  • 你代码中用到的extra方法已被Django标记为不推荐使用,可替换为Django内置的Func表达式实现相同的数字提取逻辑,兼容性更强

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:36:03