farbodg
farbodg

Reputation: 705

Comparing day ranges with Django

My table has two columns which store the days that particular deals start on and end on. The values of these columns are ints, and follow the same pattern the datetime library that Python uses.

My logic currently works for day ranges that don't wrap around the week, ie. Monday-Friday, Thursday-Saturday, Tuesday-Thursday etc. I'm not sure how to catch deals that fall into the next week, such as Friday-Monday, Saturday-Tuesday, etc. Here's my statement using Django:

Deal.objects.filter(Q(deal_day_start__lte=current_day) & Q(deal_day_end__gte=current_day))

Obviously this gives me issues for ranges Friday - Monday, since the current day for example can be Sunday, which is a 0 in datetime, and the deal start day is a 5 for Friday.

Is there an easy way to solve this using Django? If I was using Python if else statements I could obviously create several branches and capture this scenario, but I'm not sure how to go about this using Django.

Upvotes: 1

Views: 128

Answers (1)

JuniorCompressor
JuniorCompressor

Reputation: 20025

Given the used schema I would propose:

Deal.objects.filter(
  Q(deal_day_start__lte=current_day, deal_day_end__gte=current_day) | 
  Q(deal_day_start__lte=current_day, deal_day_end__lt=F("deal_day_start")) | 
  Q(deal_day_start__gte=current_day, deal_day_end__gte=current_day, deal_day_end__lt=F("deal_day_start"))
)

Let's make the observation that for a deal to wrap the end day must be smaller than the start day. We have 3 cases for current day to belong to a deal period:

  • If the current day is between start and end day.
  • If the current day is greater than the start day but greater that the end day, then it means that the deal must wrap.
  • If the current day is smaller than the start date, then the deal must wrap. But not only wrap but also finish after the current day.

Upvotes: 2

Related Questions