diff --git a/program/models.py b/program/models.py index ae93101d1f2430574e71ee2052f04fdc2e23e651..15ff88631c07996c03bf95c54718d591b0ab0dfd 100644 --- a/program/models.py +++ b/program/models.py @@ -37,27 +37,10 @@ class ScheduleConflictError(ValidationError): self.conflicts = conflicts -class ModelWithCreatedUpdatedFields(models.Model): - """Abstract model that adds: - - `created_at`, a `DateTimeField` with `auto_now_add=True` - - `updated_at`, a `DateTimeField` with `auto_now=True` - - `created_by`, a `CharField` - - `updated_by`, a `CharField` - """ - - created_at = models.DateTimeField(auto_now_add=True) - created_by = models.CharField(max_length=150) - updated_at = models.DateTimeField(auto_now=True, blank=True, null=True) - updated_by = models.CharField(blank=True, max_length=150, null=True) - - class Meta: - abstract = True - - class Type(models.Model): + is_active = models.BooleanField(default=True) name = models.CharField(max_length=32) slug = models.SlugField(max_length=32, unique=True) - is_active = models.BooleanField(default=True) class Meta: ordering = ("name",) @@ -67,11 +50,11 @@ class Type(models.Model): class Category(models.Model): + description = models.TextField(blank=True) + is_active = models.BooleanField(default=True) name = models.CharField(max_length=32) - subtitle = models.TextField(blank=True, null=True) slug = models.SlugField(max_length=32, unique=True) - is_active = models.BooleanField(default=True) - description = models.TextField(blank=True) + subtitle = models.TextField(blank=True, null=True) class Meta: ordering = ("name",) @@ -82,9 +65,9 @@ class Category(models.Model): class Topic(models.Model): + is_active = models.BooleanField(default=True) name = models.CharField(max_length=32) slug = models.SlugField(max_length=32, unique=True) - is_active = models.BooleanField(default=True) class Meta: ordering = ("name",) @@ -94,9 +77,9 @@ class Topic(models.Model): class MusicFocus(models.Model): + is_active = models.BooleanField(default=True) name = models.CharField(max_length=32) slug = models.SlugField(max_length=32, unique=True) - is_active = models.BooleanField(default=True) class Meta: ordering = ("name",) @@ -107,9 +90,9 @@ class MusicFocus(models.Model): class FundingCategory(models.Model): + is_active = models.BooleanField(default=True) name = models.CharField(max_length=32) slug = models.SlugField(max_length=32, unique=True) - is_active = models.BooleanField(default=True) class Meta: ordering = ("name",) @@ -120,8 +103,8 @@ class FundingCategory(models.Model): class Language(models.Model): - name = models.CharField(max_length=32) is_active = models.BooleanField(default=True) + name = models.CharField(max_length=32) class Meta: ordering = ("name",) @@ -160,12 +143,16 @@ class Image(models.Model): super().delete(using, keep_parents) -class Host(ModelWithCreatedUpdatedFields): +class Host(models.Model): biography = models.TextField(blank=True, null=True) + created_at = models.DateTimeField(auto_now_add=True) + created_by = models.CharField(max_length=150) email = models.EmailField(blank=True) image = models.ForeignKey(Image, null=True, on_delete=models.CASCADE, related_name="hosts") is_active = models.BooleanField(default=True) name = models.CharField(max_length=128) + updated_at = models.DateTimeField(auto_now=True, blank=True, null=True) + updated_by = models.CharField(blank=True, max_length=150, null=True) class Meta: ordering = ("name",) @@ -211,9 +198,11 @@ class LicenseType(models.Model): return self.type -class Show(ModelWithCreatedUpdatedFields): +class Show(models.Model): category = models.ManyToManyField(Category, blank=True, related_name="shows") cba_series_id = models.IntegerField(blank=True, null=True) + created_at = models.DateTimeField(auto_now_add=True) + created_by = models.CharField(max_length=150) default_playlist_id = models.IntegerField(blank=True, null=True) description = models.TextField(blank=True, null=True) email = models.EmailField(blank=True, null=True) @@ -254,6 +243,8 @@ class Show(ModelWithCreatedUpdatedFields): type = models.ForeignKey( Type, blank=True, null=True, on_delete=models.CASCADE, related_name="shows" ) + updated_at = models.DateTimeField(auto_now=True, blank=True, null=True) + updated_by = models.CharField(blank=True, max_length=150, null=True) class Meta: ordering = ("slug",) @@ -267,19 +258,6 @@ class ShowLink(Link): class RRule(models.Model): - name = models.CharField(max_length=32, unique=True) - freq = models.IntegerField( - choices=[ - (0, "once"), - (1, "monthly"), - (2, "weekly"), - (3, "daily"), - ] - ) - interval = models.IntegerField( - default=1, - help_text="The interval between each freq iteration.", - ) by_set_pos = models.IntegerField( blank=True, choices=[ @@ -307,6 +285,19 @@ class RRule(models.Model): null=True, help_text="How many occurrences should be generated.", ) + freq = models.IntegerField( + choices=[ + (0, "once"), + (1, "monthly"), + (2, "weekly"), + (3, "daily"), + ] + ) + interval = models.IntegerField( + default=1, + help_text="The interval between each freq iteration.", + ) + name = models.CharField(max_length=32, unique=True) class Meta: ordering = ("pk",) @@ -318,17 +309,20 @@ class RRule(models.Model): class Schedule(models.Model): - rrule = models.ForeignKey( - RRule, - on_delete=models.CASCADE, - related_name="schedules", - help_text="A recurrence rule.", + add_business_days_only = models.BooleanField( + default=False, + help_text=( + "Whether to add add_days_no but skipping the weekends. " + "E.g. if weekday is Friday, the date returned will be the next Monday." + ), ) - show = models.ForeignKey( - Show, - on_delete=models.CASCADE, - related_name="schedules", - help_text="Show the schedule belongs to.", + add_days_no = models.IntegerField( + blank=True, + null=True, + help_text=( + "Add a number of days to the generated dates. " + "This can be useful for repetitions, like 'On the following day'." + ), ) by_weekday = models.IntegerField( help_text="Number of the Weekday.", @@ -343,34 +337,31 @@ class Schedule(models.Model): ], null=True, ) - first_date = models.DateField(help_text="Start date of schedule.") - start_time = models.TimeField(help_text="Start time of schedule.") + default_playlist_id = models.IntegerField( + blank=True, + null=True, + help_text="A tank ID in case the timeslot's playlist_id is empty.", + ) end_time = models.TimeField(help_text="End time of schedule.") - last_date = models.DateField(help_text="End date of schedule.") + first_date = models.DateField(help_text="Start date of schedule.") is_repetition = models.BooleanField( default=False, help_text="Whether the schedule is a repetition.", ) - add_days_no = models.IntegerField( - blank=True, - null=True, - help_text=( - "Add a number of days to the generated dates. " - "This can be useful for repetitions, like 'On the following day'." - ), - ) - add_business_days_only = models.BooleanField( - default=False, - help_text=( - "Whether to add add_days_no but skipping the weekends. " - "E.g. if weekday is Friday, the date returned will be the next Monday." - ), + last_date = models.DateField(help_text="End date of schedule.") + rrule = models.ForeignKey( + RRule, + on_delete=models.CASCADE, + related_name="schedules", + help_text="A recurrence rule.", ) - default_playlist_id = models.IntegerField( - blank=True, - null=True, - help_text="A tank ID in case the timeslot's playlist_id is empty.", + show = models.ForeignKey( + Show, + on_delete=models.CASCADE, + related_name="schedules", + help_text="Show the schedule belongs to.", ) + start_time = models.TimeField(help_text="Start time of schedule.") class Meta: ordering = ("first_date", "start_time") @@ -410,13 +401,10 @@ class TimeSlotManager(models.Manager): class TimeSlot(models.Model): - schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE, related_name="timeslots") - show = models.ForeignKey( - Show, editable=False, on_delete=models.CASCADE, related_name="timeslots" - ) - start = models.DateTimeField() end = models.DateTimeField() memo = models.TextField(blank=True) + note_id = models.IntegerField(null=True, editable=False) + playlist_id = models.IntegerField(null=True) repetition_of = models.ForeignKey( "self", blank=True, @@ -424,8 +412,11 @@ class TimeSlot(models.Model): on_delete=models.CASCADE, related_name="repetitions", ) - playlist_id = models.IntegerField(null=True) - note_id = models.IntegerField(null=True, editable=False) + schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE, related_name="timeslots") + show = models.ForeignKey( + Show, editable=False, on_delete=models.CASCADE, related_name="timeslots" + ) + start = models.DateTimeField() objects = TimeSlotManager() @@ -462,13 +453,19 @@ class TimeSlot(models.Model): return str("".join(s for s in string if s.isdigit())) -class Note(ModelWithCreatedUpdatedFields): - contributors = models.ManyToManyField(Host, related_name="contributions") +class Note(models.Model): cba_id = models.IntegerField(blank=True, null=True) content = models.TextField() + contributors = models.ManyToManyField(Host, related_name="contributions") + created_at = models.DateTimeField(auto_now_add=True) + created_by = models.CharField(max_length=150) image = models.ForeignKey(Image, null=True, on_delete=models.CASCADE, related_name="notes") owner = models.ForeignKey( - User, editable=False, on_delete=models.CASCADE, related_name="notes", default=1 + User, + editable=False, + on_delete=models.CASCADE, + related_name="notes", + default=1, ) playlist = models.TextField(blank=True, null=True) slug = models.SlugField(max_length=32, unique=True) @@ -476,6 +473,8 @@ class Note(ModelWithCreatedUpdatedFields): tags = models.TextField(blank=True, null=True) timeslot = models.OneToOneField(TimeSlot, on_delete=models.CASCADE, unique=True) title = models.CharField(max_length=128) + updated_at = models.DateTimeField(auto_now=True, blank=True, null=True) + updated_by = models.CharField(blank=True, max_length=150, null=True) class Meta: ordering = ("timeslot",) @@ -495,12 +494,19 @@ class NoteLink(Link): note = models.ForeignKey(Note, on_delete=models.CASCADE, related_name="links") -class UserProfile(ModelWithCreatedUpdatedFields, models.Model): - user = models.OneToOneField( - User, on_delete=models.CASCADE, related_name="profile", editable=False - ) +class UserProfile(models.Model): cba_username = models.CharField("CBA Username", blank=True, max_length=60) cba_user_token = models.CharField("CBA Token", blank=True, max_length=255) + created_at = models.DateTimeField(auto_now_add=True) + created_by = models.CharField(max_length=150) + updated_at = models.DateTimeField(auto_now=True, blank=True, null=True) + updated_by = models.CharField(blank=True, max_length=150, null=True) + user = models.OneToOneField( + User, + on_delete=models.CASCADE, + related_name="profile", + editable=False, + ) def __str__(self): return self.user.username