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

如何在Django中跨三个关联模型查询用户所属全部Campaign

问题描述

我正在使用Django,希望了解如何通过三个关联模型获取对象。以下是我的模型代码:

class Participant(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    is_leader = models.BooleanField(default=False)
    team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True, related_name="participants")
    application_date = models.DateField(auto_now_add=True, null=True)
    resolution_date = models.DateField(null=True, blank=True)
    accepted = models.BooleanField(default=False)

class Team(models.Model):
    name = models.TextField(default="")
    is_public = models.BooleanField(default=False)
    institution = models.ForeignKey(Institution, on_delete=models.CASCADE, null=True, related_name='teams')
    campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE, null=True, related_name='teams')

class Campaign(models.Model):
    name = models.TextField(default="")
    description = models.TextField(default="")
    initial_date = models.DateTimeField(auto_now_add=False, null=True, blank=True)
    end_date = models.DateTimeField(auto_now_add=False, null=True, blank=True)
    qr_step_enabled = models.BooleanField(default=True)
    image_resolution = models.IntegerField(default=800)
    sponsor = models.ForeignKey(Sponsor, on_delete=models.CASCADE, null=True, related_name='campaigns')

我已通过request获取到user对象,想要获取该用户所属的全部Campaign。原本我使用循环实现:

user = request.user
participants = user.participant_set.all()
for participant in participants:
  participant.team.campaign.name

请问是否可以通过跨模型查询实现该需求?用户可拥有多个Participant,每个Participant对应一个Team,每个Team对应一个Campaign。

解决方案

当然可以通过Django的跨模型关联查询直接实现,不需要循环遍历,还能避免N+1数据库查询问题,提升效率。以下是几种可行方式:

方式一:从Campaign模型反向关联查询

利用Django的双下划线__实现跨模型筛选,直接定位到关联当前用户的Campaign:

user = request.user
campaigns = Campaign.objects.filter(teams__participants__user=user).distinct()
  • teams__participants__user表示:Campaign关联的Team → Team关联的Participant → Participant关联的User等于当前用户
  • .distinct()用于去重,避免同一个Campaign因用户多个Participant关联而重复出现

方式二:从User模型正向关联查询

从当前用户出发,通过关联的Participant、Team反向定位到Campaign:

user = request.user
# 获取完整的Campaign对象
campaigns = Campaign.objects.filter(id__in=user.participant_set.values_list('team__campaign__id', flat=True)).distinct()

# 若只需获取Campaign的ID,可直接用values_list
campaign_ids = user.participant_set.values_list('team__campaign__id', flat=True).distinct()

方式三:优化原循环逻辑(可选)

如果需要保留循环处理逻辑,可通过select_related预加载关联对象,减少数据库查询次数:

user = request.user
# 提前预加载team和campaign,仅发起1次数据库查询
participants = user.participant_set.select_related('team__campaign').all()
for participant in participants:
    print(participant.team.campaign.name)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:55:40