我可以过滤用户在给定范围内的每个日期都要求匹配的条目吗?

时间:2015-07-21 18:42:25

标签: python django django-rest-framework

是否可以过滤查询集,以便仅检索范围内每个日期的匹配对象的用户?

例如,我有一个Shift模型,其中包含指向ForeignKey对象的Employee字段和指示日期的date_requested DateField转移。我还创建了以下查询,用于抓取任何没有转换的用户,例如2015-07-192015-07-25

Employee.objects.all().exclude(
    shift__date_requested__gte=datetime.date(2015, 7, 19),
    shift__date_requested__lte=datetime.date(2015, 7, 25))

不幸的是,这个查询集没有捕获指定从07/19到07/24的转换的用户,但没有捕获07/25的转换。是否可以进一步优化此查询,以说明“2015-07-192015-07-25(包括)之间与此用户相关的班次数必须等于此时间范围内的天数?

编辑:以下是根据以下答案之一运行的一些代码:

首先,显示员工#10在7/19到7/25之间每天都有Shift的数据集。这应该导致它们被过滤掉:

Dataset

我的过滤代码

e = Employee.objects.all()
print('all employees:\n{0}'.format(e))
for day in range(19, 26):
    print('filtering day {0}'.format(day))
    e.filter(shift__date_requested=datetime.date(2015, 7, day))

print('filtered employees:\n{0}'.format(e))

结果输出:

all employees:
[<Employee: 12: ereiner@test.com ()>, <Employee: 10: alufson@test.com ()>, <Employee: 11: tjones@test.com ()>,
<Employee: 14: wmcgee@test.com ()>, <Employee: 13: wcarver@test.com ()>]
filtering day 19
filtering day 20
filtering day 21
filtering day 22
filtering day 23
filtering day 24
filtering day 25
filtered employees:
[<Employee: 12: ereiner@test.com ()>, <Employee: 10: alufson@test.com ()>, <Employee: 11: tjones@test.com ()>,
<Employee: 14: wmcgee@test.com ()>, <Employee: 13: wcarver@test.com ()>]

如您所见,员工10未被过滤掉。我还尝试用filter()换出exclude(),但我看到了相同的结果

2 个答案:

答案 0 :(得分:0)

如果您希望获得一个对每个给定日期都没有轮班的员工的查询集:

employees = Employee.objects.all()
for day in range(19, 26):
    employees = employees.filter(shift__date_requested=datetime.date(2015, 7, day))

请注意链接过滤器does not hit the database multiple times

答案 1 :(得分:0)

我希望我的问题是对的。

def get_num_days(d1, d2):
    return abs((d1 - d2).days)

d1 = datetime.date(2015, 7, 19)
d2 = datetime.date(2015, 7, 25)
num_days = get_num_days(d1, d2)

employees = Employee.objects \
            .annotate(num_shifts=Count('shift__date_requested', distinct=True)) \
            .exclude(num_shifts=num_days, shift__date_requested__range=(d1, d2))

如果员工的不同班次'date_requested等于两个日期之间的天数,则这些班次将填写两个日期之间范围内的每个日期。我使用distinct因为我不清楚员工的班次是否可以有date_requested