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

Django如何按预约项数量注解员工并按预约时间筛选

正确实现方法

你的代码存在关联路径错误和反向关联名称使用不当的问题,以下是修正后的实现方案:

基础版(仅统计有符合条件预约项的员工)

from django.db.models import Count

employee_list = Employee.objects.filter(
    gym_id=1,
    # 通过AppointmentItem间接关联到Appointment,筛选指定时间后的预约
    appointmentitem__appointment__time__gte='2022-07-10'
).annotate(
    # 统计员工的有效预约项数量,distinct=True避免重复计数
    item_count=Count('appointmentitem', distinct=True)
).order_by('-item_count')  # 可选,按预约项数量降序排列

进阶版(包含健身房内所有员工,无符合条件项则计数为0)

如果需要展示健身房1的所有员工,即使没有符合时间条件的预约项也显示(计数为0),可以使用带过滤条件的annotate:

from django.db.models import Count, Q

employee_list = Employee.objects.filter(
    gym_id=1
).annotate(
    item_count=Count(
        'appointmentitem',
        # 仅统计满足时间条件的预约项
        filter=Q(appointmentitem__appointment__time__gte='2022-07-10'),
        distinct=True
    )
).order_by('-item_count')

关键修正说明

  1. 关联路径修正:Employee和Appointment没有直接外键关联,必须通过中间模型AppointmentItem建立关联,因此筛选预约时间需要写成appointmentitem__appointment__time,而非直接的appointment__time。
  2. 反向关联名称:AppointmentItem的外键指向Employee,Django默认的反向关联名称是appointmentitem_set,但在annotate/filter中可以直接使用小写模型名appointmentitem,写法更简洁。
  3. 去重计数:添加distinct=True是为了避免同一个预约(Appointment)下有多个预约项(AppointmentItem)时,导致员工被重复统计,确保每个预约项只被计数一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:54:22