Skip to content

Instantly share code, notes, and snippets.

@asmallteapot
Created January 31, 2012 21:56
Show Gist options
  • Select an option

  • Save asmallteapot/1713238 to your computer and use it in GitHub Desktop.

Select an option

Save asmallteapot/1713238 to your computer and use it in GitHub Desktop.
[Django] Validate that each day of the week is used in up to one set of opening hours. Includes user–friendly error messages.
from django.core.exceptions import ValidationError
WEEKDAYS = (
(1, 'Monday'),
(2, 'Tuesday'),
(3, 'Wednesday'),
(4, 'Thursday'),
(5, 'Friday'),
(6, 'Saturday'),
(7, 'Sunday'),
)
def clean(self):
"""Validate that this set of opening hours doesn't conflict with another."""
# we'll never have the first two sets of opening hours on the first iteration
last_hours = False
for hours in self.location.hours:
# skip the first iteration so we always have two sets of opening hours to analyse
if last_hours == False:
last_hours = hours
continue
# make ranges of the weekdays involved
last_days = range(last_hours.weekday_from, last_hours.weekday_to)
days = range(hours.weekday_from, hours.weekday_to)
# for all days in last_days, collect it, if it's also in days
overlap = [day for day in last_days if day in days]
# a day cannot be in two sets of opening hours
if overlap.count() > 0:
# convert weekday numbers into a comma-separated list of weekdays
if overlap.count() == 1:
weekdays = WEEKDAYS[overlap[0]][1]
elif overlap.count() == 2:
weekday1 = WEEKDAYS[overlap[0]][1]
weekday2 = WEEKDAYS[overlap[1]][1]
weekdays = '%s and %s' % (weekday1, weekday2)
else:
last_day = overlap.pop()
weekdays = ', '.join(WEEKDAYS[day][1] for day in overlap)
weekdays = '%s, and %s' % (weekdays, last_day)
message = 'Opening hours for %s are already set.' % weekdays
raise ValidationError(message)
# compare with this set of opening hours on the next iteration
last_hours = hours
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment