Option (and faster) - use bitmasks!
Think about the days of the week when you want the chore to be repeated as a binary number - a bit for each day. For example, if you want the chorus to be repeated every Tuesday, Friday, and Sunday, you get the binary number 1010010 (or 82 in decimal):
SSFTWTM 1 0 1 0 0 1 0 = 1010010
Days are reversed to illustrate.
And to check if you need to do the work today, just enter the number of this day and do & :
from datetime import datetime as dt if dt.today().weekday() & 0b1010100: print("Do chores!")
Models
Your .py models would look something like this:
from django.contrib.auth.models import User from django.db import models from django.utils.functional import cached_property class Chore(models.Model): name = models.CharField(max_length=128) notes = models.TextField() class ChoreUser(models.Model): chore_detail = models.ForeignKey('ChoreDetail') user = models.ForeignKey('ChoreDetail') completed_time = models.DateTimeField(null=True, blank=True) class ChoreDetail(models.Model): chore = models.ForeignKey('Chore') chore_users = models.ManyToManyField('User', through=ChoreUser) time = models.DateTimeField() date_begin = models.DateField() date_end = models.DateField() schedule = models.IntegerField(help_text="Bitmask of Weekdays") @cached_property def happens_today(self): return bool(dt.today().weekday() & self.weekly_schedule)
This scheme has an M2M relationship between the User and the Hourly Schedule. Thus, you can expand your idea, for example, by recording the duration of work (if you want) or even many users participating in the same work.
And to answer your question, if you want a list of completed events this week, you could put this in the model manager for ChoreUser :
from datetime import datetime as dt, timedelta week_start = dt.today() - timedelta(days=dt.weekday()) week_end = week_start + timedelta(days=6) chore_users = ChoreUser.objects.filter(completed_time__range=(week_start, week_end))
Now you have all the necessary information in one DB call:
user = chore_users[0].user time = chore_users[0].chore_detail.time name = chore_users[0].chore_detail.chore.name happens_today = chore_users[0].chore_detail.happens_today
You can also easily get all completed tasks for the user:
some_user.choreuser_set.filter(completed_time__range=(week_start, week_end))