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

