Django ORM外键关联查询:获取指定组织下的所有主机QuerySet
Django ORM查询特定组织下所有主机的解决方案
没问题,我来帮你搞定这个查询需求!首先先基于你描述的关联关系,给出一个典型的模型结构参考(如果你的实际模型字段名有差异,对应调整即可):
from django.db import models class Organisations(models.Model): name = models.CharField(max_length=100) # 其他业务字段... class Groups(models.Model): # 关联所属组织,related_name用于反向查询 organisation = models.ForeignKey(Organisations, on_delete=models.CASCADE, related_name="groups") # 其他业务字段... class Hosts(models.Model): # 关联所属分组,related_name用于反向查询 group = models.ForeignKey(Groups, on_delete=models.CASCADE, related_name="hosts") # 其他业务字段...
接下来给你两种简单直接的查询方式:
方式一:从Hosts模型直接跨关联过滤
利用Django ORM的双下划线跨关联查询特性,直接从Hosts出发,层层穿透外键关联到Organisations进行过滤:
# 获取名称为'Y'的组织下的所有主机QuerySet target_hosts = Hosts.objects.filter(group__organisation__name='Y')
这里的group__organisation__name就是依次通过Hosts的group外键关联到Groups,再通过Groups的organisation外键关联到Organisations,最终过滤出组织名称为'Y'的所有主机。
方式二:从Organisations模型反向关联查询
如果你需要先拿到目标组织对象,再基于它获取下属的主机,也可以这么写:
# 先获取目标组织(如果存在多个同名组织,建议用filter而非get避免异常) target_org = Organisations.objects.get(name='Y') # 方式1:通过组织反向关联到分组,再过滤主机 target_hosts = Hosts.objects.filter(group__in=target_org.groups.all()) # 方式2:更简洁的链式写法,和方式一逻辑一致 target_hosts = Hosts.objects.filter(group__organisation=target_org)
如果你的模型里没设置related_name,Django会自动生成默认的反向关联名称,格式是模型名小写_set,比如Organisations的反向分组就是groups_set,这时候上面的代码要改成target_org.groups_set.all()。
一些注意事项
- 确保查询语句里的字段名和你实际models.py里的外键字段名完全一致,比如如果Groups里关联组织的字段叫
org,那就要写成group__org__name - 如果组织名称可能重复,用
Organisations.objects.filter(name='Y')代替get,避免抛出MultipleObjectsReturned异常 - 所有返回的结果都是Django的QuerySet,支持后续的链式操作(比如排序、分页、序列化等),而且是懒加载的,只有当你实际使用这个QuerySet时才会执行数据库查询
内容的提问来源于stack exchange,提问作者user4227817
相关产品推荐
相关产品推荐

