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

Django中使用ForeignKey时_set()和filter()方法有什么区别?

Django 反向关联 _set 查询的优势

首先要明确:这两种写法生成的SQL几乎完全一致,返回的结果也没有区别,但是使用反向关联的 _set 写法有几个非常实际的好处:

  • 写法更简洁,可维护性更高
    不需要显式引入 Order 模型,也不用手动编写外键过滤条件,拿到用户实例就能直接获取关联订单。如果后续外键字段改名,只要你设置的 related_name 不变,反向关联的写法不需要做任何修改;但直接用 filter 的写法里,过滤参数的字段名就要跟着同步修改,容易出现漏改的问题。
  • 天然适配ORM查询优化逻辑
    如果你提前用 prefetch_related 预取了用户的关联订单数据,调用 user.order_set.all() 会直接复用缓存的结果,不会触发额外的数据库查询。但如果在循环中调用 Order.objects.filter(user=user),每次都会生成新的查询请求,数据量大的时候性能差距会非常明显。
    示例预取写法:
    # 只会触发两次查询,一次查用户,一次查所有关联订单
    users = User.objects.prefetch_related("order_set").all()
    for user in users:
        # 不会产生新的查询
        orders = user.order_set.all()
    
  • 可以直接复用模型管理器的自定义方法
    如果你给 Order 模型的管理器写了自定义方法,比如用来筛选已支付订单的 paid() 方法,用反向关联可以直接调用:user.order_set.paid(),和直接调用管理器的写法完全一致,不需要额外适配。
  • 降低出错概率
    反向关联天然绑定了当前实例的主键作为过滤条件,不会出现手动写 filter 时传错参数、写错字段名的低级错误。

小提示:如果外键字段设置了自定义的 related_name 参数,直接用你设置的名称替换默认的 order_set 即可,用法完全相同。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:15:01