I need to build a formset to allow opening hours to be set for a week.
Here is my model for opening times:
WEEKDAYS = [
(1, _("Monday")),
(2, _("Tuesday")),
(3, _("Wednesday")),
(4, _("Thursday")),
(5, _("Friday")),
(6, _("Saturday")),
(7, _("Sunday")),
]
class OpeningHours(models.Model):
user = models.ForeignKey(User)
weekday = models.IntegerField(choices=WEEKDAYS)
from_hour = models.TimeField()
to_hour = models.TimeField()
class Meta:
unique_together = (('user', 'weekday'),)
Here is how I generate a formset for a default week setting
UserOpeningHoursFormSet = formset_factory(UserOpeningHoursForm, extra=0)
hours = [{
'weekday': day,
'from_hour': '08:00',
'to_hour': '18:00',
} for day in range(1, 8)]
formset = UserOpeningHoursFormSet(initial=hours)
Here is how I get opening hours for the current user
user_hours = request.user.openinghours_set.all()
How can I put the user_hours into my formset ?
Edit
Example, let's say the user already has the hours for Monday and Thursday set in the db, the form should resemble:
weekday: Monday
from_hour: '09:00' # user_set
to_hour: '19:00' # user_set
weekday: Tuesday
from_hour: # default initial value
to_hour: # default initial value
weekday: Wednesday
from_hour: # default initial value
to_hour: # default initial value
weekday: Thursday
from_hour: '13:00' # user_set
to_hour: '15:00' # user_set
weekday: Friday
from_hour: # default initial value
to_hour: # default initial value
weekday: Saturday
from_hour: # default initial value
to_hour: # default initial value
Expanding on @Rohan's answer:
I don't think modelformset is neccessary, just construct the hours like this
hours = [
{'weekday': day, 'from_hour': '08:00', 'to_hour': '18:00'}
for day in range(1, 8) if not any(request.user.openinghours_set.filter(weekday=day))
else
{'weekday': day, 'from_hour': request.user.openinghours_set.filter(weekday=day).from_hour,
'to_hour': request.user.openinghours_set.filter(weekday=day).to_hour}
]
Obviously, this is inefficient as it constructs one or three queryset(s) for each day, so rewriting it like this:
hours = []
openinghours_set = list(request.user.openinghours_set.all())
for day in range(1, 8):
for openinghours in openinghours_set:
if openinghours.weekday == day:
hours.append({ fill from *openinghours* })
break
else:
hours.append({ fill with default values })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With