Django的工作日
Posted
技术标签:
【中文标题】Django的工作日【英文标题】:Business days in Django 【发布时间】:2013-07-24 19:07:56 【问题描述】:我需要实施使用工作日的有条件休息。我有一个带有DateField
的课程,如果该日期在未来不到5 个工作日,就会发生某些事情(动作a
),否则会发生b
。如何确定两个对象之间的工作日数?
显然,我需要计算从今天起的 5 个工作日。使用简单的时间增量查找未来 5 天很容易,但要考虑工作日,它会变得更加复杂。我想我现在可以放心地忽略假期(这不是最好的情况,但我认为只要工作日是周一到周五就可以了)。谁能给我一些指导,告诉我如何做类似的事情:target = today + 5 business_days
?
谢谢
【问题讨论】:
如果您不计算节假日,而您总是计算五个工作日,那么每次不就是一个日历周吗?从周一开始的五个工作日就是下周一,以此类推。 天啊……当然是…… @PeterDeGlopper - 仅当开始日期也是工作日时 在这种情况下,我几乎可以保证它会。 然后是的,再加上 7 天,一切就绪。 【参考方案1】:这是一个通用的解决方案,即使您的情况非常简单;P
from datetime import timedelta, date
def add_business_days(from_date, number_of_days):
to_date = from_date
while number_of_days:
to_date += timedelta(1)
if to_date.weekday() < 5: # i.e. is not saturday or sunday
number_of_days -= 1
return to_date
还有结果。
>>> date.today()
datetime.date(2013, 7, 25)
>>> add_business_days(date.today(), 6)
datetime.date(2013, 8, 2)
如果您在 if 语句中检查日期是否为假日,则加分。
【讨论】:
谢谢!我会接受这个答案,但我会说这很简单,甚至没有保证。我为自己没有想到这一点而感到非常愚蠢。 “仅当开始日期也是工作日”“在这种情况下,我几乎可以保证它会是。”你真的能保证吗?如果没有,你可能最终还是会使用这段代码。【参考方案2】:此示例是当您将 django 项目作为 API 制作时
您可以使用Numpy 获得工作日,它使用SCIPY(查看更多详细信息)
您必须通过pip
安装numpy
pip install numpy
pip3 install numpy
在models.py
中添加取决于您要放置属性方法的位置:
class WorkingDay(models.Model):
# YY-MM-DD
start = models.DateField(null=True, verbose_name="start")
end = models.DateField(null=True, verbose_name="end")
@property
def workdays(self):
total = np.busday_count(self.start, self.end)
return total
那么在你的serializers.py
中你可能会有这样的东西。
class WorkingDaySerializer(serializers.ModelSerializer):
workdays = serializers.IntegerField(read_only=True)
class Meta:
model = WorkingDay
fields = '__all__'
read_only_fields = ['workdays']
在你看来,你可能会做这样的事情。
class WorkingDayAPI(APIView):
"""
"start":"2018-01-01",
"end":"2018-05-01"
GET work days between dates
"""
serializer_class = WorkingDaySerializer
def get(self, request, format=None):
business_days = WorkingDay.objects.all()
serializer = WorkingDaySerializer(business_days, many=True)
return Response(serializer.data)
def post(self, request, *args, **kwargs):
start = request.data.get('start')
end = request.data.get('end')
# bizdays = request.data.get('bizdays')
business_days = WorkingDay.objects.create(**request.data)
business_days.start = start
business_days.end = end
business_days.workdays = workdays
business_days.save()
serializer = WorkingDaySerializer(business_days)
return Response(serializer.data, status=status.HTTP_201_CREATED)
【讨论】:
以上是关于Django的工作日的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django 中为 celery beat 设置不同的工作日/周末时间表?
django:DetailView 如何为两个模型工作或基于类的视图如何为两个模型工作?