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
相关产品推荐
相关产品推荐

