Django ORM反向关联查询求助:通过User ID获取全层级数据
通过User ID获取全层级关联数据的Django ORM实现
首先修正你提供的模型中的语法与拼写错误(符合Django模型规范的写法如下):
from django.contrib.auth.models import User from django.db import models class UserProfile(models.Model): user = models.ForeignKey(User, related_name='fU', on_delete=models.CASCADE) class A(models.Model): user_profile = models.ForeignKey(UserProfile, related_name='fa', on_delete=models.CASCADE) class B(models.Model): a = models.ForeignKey(A, related_name='fb', on_delete=models.CASCADE) class C(models.Model): b = models.ForeignKey(B, related_name='fC', on_delete=models.CASCADE)
方法1:逐层遍历关联数据
已知目标User的ID时,可从User对象出发,通过反向关联逐层获取所有层级的数据:
target_user_id = 1 # 获取目标User实例 user = User.objects.get(id=target_user_id) # 拿到关联的所有UserProfile user_profiles = user.fU.all() # 遍历所有层级 for profile in user_profiles: for a_instance in profile.fa.all(): for b_instance in a_instance.fb.all(): c_instances = b_instance.fC.all() # 此处可处理每个C实例的数据,比如打印或存储 print(c_instances)
方法2:预取关联数据优化查询
上述方法会触发多次数据库查询,数据量较大时性能不佳,推荐使用prefetch_related预取所有层级关联,避免N+1查询问题:
target_user_id = 1 # 一次性预取所有层级的关联数据 user = User.objects.prefetch_related( 'fU', 'fU__fa', 'fU__fa__fb', 'fU__fa__fb__fC' ).get(id=target_user_id) # 后续遍历不会触发额外数据库查询 for profile in user.fU.all(): for a_instance in profile.fa.all(): for b_instance in a_instance.fb.all(): print(b_instance.fC.all())
方法3:直接获取底层C数据
若只需获取该User关联的所有C实例,可直接从C模型反向查询:
target_user_id = 1 # 直接过滤出关联的C实例 c_instances = C.objects.filter( b__a__user_profile__user_id=target_user_id ) # 若需要同时获取上层关联对象,用select_related优化 c_instances = C.objects.select_related('b', 'b__a', 'b__a__user_profile').filter( b__a__user_profile__user_id=target_user_id )
内容的提问来源于stack exchange,提问作者user3402966
相关产品推荐
相关产品推荐

