I'm creating an app for an educational school. The school has a RegularSchoolClass class (inherits from a base SchoolClass class) and also has a LessonSchedule class that tracks the schedule of a class.
In particular, the SchoolClass (base class) has a many-to-many relationship with LessonSchedule. In particular, a SchoolClass object should have 48 lesson schedules (e.g. week 0, week 1, week 2; 48 lessons in a year). At the same time, a particular lesson schedule could be shared by multiple SchoolClass objects, hence I chose a many-to-many relationship.
I wrote some logic that whenever a user changes the day of a class in the admin console, it should automatically change all the LessonScheules linked to the class. For instance, if a class was originally on a tuesday, and it switched to a wednesday, then all the lesson schedules should be switched accordingly.
What's weird is that this doesn't show up in the admin console - it defaults to 0 lesson schedule, even after I save. But in the console, self.lesson_schedule.all().count() shows 48. Wondering if someone could guide me to the right answer?
I checked (Saving Many To Many data via a modelform in Django) and my case seems to be different since I have already saved the parent object (I'm using post-save)
models.py (for school class)
class SchoolClass(TimeStampedModel):
lesson_schedule = models.ManyToManyField('LessonSchedule', null=True, blank=True)
day = models.IntegerField(choices=DAYS, null=True)
start_date = models.DateField(null=True)
def __str__(self):
return '{}'.format(self.lesson_schedule.all().count())
class RegularSchoolClass(DirtyFieldsMixin, SchoolClass):
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
def save_without_signals(self):
setattr(self, '_disable_signals', True)
self.save()
#this correctly prints 48 -> so lesson_schedule should be linked correctly
print(self.lesson_schedule.all().count())
setattr(self, '_disable_signals', False)
@receiver(post_save, sender=RegularSchoolClass)
def post_save_regular_school_class(sender, instance, created, **kwargs):
#https://stackoverflow.com/questions/10840030/django-post-save-preventing-recursion-without-overriding-model-save
#prevents infinite saving
if getattr(instance, '_disable_signals', False):
return
#for new instances or when we have changed the day, we want to update start_date
#and assign lesson schedules
if created or (instance.is_dirty() and 'day' in instance.get_dirty_fields()):
# existing lesson schedule needs to be unlinked
for l in instance.lesson_schedule.all():
instance.lesson_schedule.remove(l)
#assigning new lesson schedule
for l in LessonSchedule.objects.filter(start_date=instance.start_date):
instance.lesson_schedule.add(l)
instance.save_without_signals()
models.py (for lessonschedule)
#used to track the day for a lesson
#for regular classes, start_date should be the date of the first lesson in the year
class LessonSchedule(models.Model):
start_date = models.DateField()
lesson_index = models.IntegerField()
lesson_date = models.DateField()
class Meta:
unique_together = 'start_date', 'lesson_index')