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

Django:基于多对多与外键实现用户专属Schedule查询集

解决方案

首先修正模型中的笔误:Event类里关联的是Booking,但你的模型类名为Bookings,需要统一为Booking(或者调整关联名称),否则会报错。修正后的模型关键部分如下:

class Booking(models.Model):  # 修正类名为Booking
    user = models.ForeignKey(
        User, 
        blank=True, 
        null=True, 
        on_delete=models.SET_NULL)

class Event(models.Model):
    bookings = models.ManyToManyField(
        Booking,  # 对应修正后的类名
        related_name="event_bookings", 
        blank=True)

接下来修改ScheduleManager的for_user方法,通过双下划线跨表过滤直接获取指定用户的Schedule查询集,同时结合查询优化方法减少数据库请求:

class ScheduleManager(models.Manager):
    def for_user(self, user):
        """
        Returns a Schedule queryset for a given user object.
        Usage:
            user= User.objects.first()
            Schedule.objects.for_user(user)
        """
        return self.get_queryset().filter(
            event__bookings__user=user
        ).select_related('event').distinct()

关键说明

  • event__bookings__user=user:通过双下划线跨表关联Schedule→Event→Booking→User,直接过滤出属于目标用户的日程。
  • .distinct():由于多对多关联可能导致同一Schedule被多次匹配,用该方法去重。
  • .select_related('event'):提前预加载关联的Event对象,避免后续访问Schedule.event时触发额外数据库查询。

如果需要进一步预加载Booking和User信息,可以结合prefetch_related扩展:

return self.get_queryset().filter(
    event__bookings__user=user
).select_related('event').prefetch_related(
    'event__bookings'
).distinct()

这种方式仅需1-2次数据库请求,彻底解决循环查询导致的N+1问题,代码简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:25:29