django-openinghours
django-openinghours copied to clipboard
how to make query that returns companies that are open?
I would like to do something like this: open_shops = Shop.objects.filter(is_open=True) But how ? :)
and I'd like to add is_open to my model.
update: Im thinking something like adding this to my Shop model:
@property
def tz_info(self):
return geocoders.GoogleV3().timezone((self.location.y,self.location.x))
@property
def is_open(self):
now = datetime.now(tz=self.tz_info)
now_time = time(now.hour, now.minute, now.second)
if not ClosingRules.objects.filter(company=self, start__lte=now, end__gte=now).count():
ohs = OpeningHours.objects.filter(company=self)
for oh in ohs:
is_open = False
# start and end is on the same day
if (oh.weekday == now.isoweekday() and oh.from_hour <= now_time and now_time <= oh.to_hour):
is_open = oh
# start and end are not on the same day and we test on the start day
if (oh.weekday == now.isoweekday() and oh.from_hour <= now_time and ((oh.to_hour < oh.from_hour) and (now_time < time(23, 59, 59)))):
is_open = oh
# start and end are not on the same day and we test on the end day
if (oh.weekday == (now.isoweekday() - 1) % 7 and oh.from_hour >= now_time and oh.to_hour >= now_time and oh.to_hour < oh.from_hour):
is_open = oh
# print " 'Special' case after midnight", oh
if is_open is not False:
return oh
return False
You can try using Q and F objects:
from django.db.models import Q, F
Company.objects.filter(
~Q(closingrules__start__lte=now, closingrules_set__end__gte=now)
&
(
Q(
openinghours__weekday=now.isoweekday(),
openinghours__from_hour__lte=now_time,
openinghours__to_hour__gte=now_time,
) | Q(
openinghours__weekday=now.isoweekday(),
openinghours__from_hour__lte=now_time,
openinghours__to_hour__lt=F('openinghours__from_hour'),
) | Q(
openinghours__weekday=(now.isoweekday() - 1) % 7,
openinghours__from_hour__gte=now_time,
openinghours__to_hour__gte=now_time,
)
)
)
If you really need it to be like "property" then you can also try annotating queryset