From 49bbd18997f933fdcc310da336930e2c91d92df0 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Tue, 22 Oct 2024 18:52:04 +0200 Subject: [PATCH] Remove "next_day" foreign key Days now just have an order field, which is much easier to work with, specially over the API --- wger/manager/api/serializers.py | 6 ++--- wger/manager/api/views.py | 2 +- wger/manager/fixtures/test-routine-data.json | 6 ++--- .../commands/dummy-generator-routines.py | 20 +++------------ .../migrations/0018_flexible_routines.py | 21 ++-------------- .../0019_flexible_routines_migration.py | 8 +----- wger/manager/models/abstract_config.py | 1 + wger/manager/models/day.py | 14 +++++++---- wger/manager/models/routine.py | 25 ++++++------------- wger/manager/models/slot.py | 2 +- wger/manager/tests/test_routine.py | 16 +++--------- 11 files changed, 33 insertions(+), 88 deletions(-) diff --git a/wger/manager/api/serializers.py b/wger/manager/api/serializers.py index feb708dc0..234881ec5 100644 --- a/wger/manager/api/serializers.py +++ b/wger/manager/api/serializers.py @@ -52,7 +52,6 @@ class RoutineSerializer(serializers.ModelSerializer): 'id', 'name', 'description', - 'first_day', 'created', 'start', 'end', @@ -69,7 +68,7 @@ class DaySerializer(serializers.ModelSerializer): fields = ( 'id', 'routine', - 'next_day', + 'order', 'name', 'description', 'is_rest', @@ -243,7 +242,7 @@ class DayStructureSerializer(serializers.ModelSerializer): fields = ( 'id', 'routine', - 'next_day', + 'order', 'name', 'description', 'is_rest', @@ -266,7 +265,6 @@ class RoutineStructureSerializer(serializers.ModelSerializer): 'id', 'name', 'description', - 'first_day', 'created', 'start', 'end', diff --git a/wger/manager/api/views.py b/wger/manager/api/views.py index ccb93633f..dea482507 100644 --- a/wger/manager/api/views.py +++ b/wger/manager/api/views.py @@ -452,7 +452,7 @@ class RoutineDayViewSet(WgerOwnerObjectModelViewSet): ordering_fields = '__all__' filterset_fields = ( 'id', - 'next_day', + 'order', 'name', 'description', 'is_rest', diff --git a/wger/manager/fixtures/test-routine-data.json b/wger/manager/fixtures/test-routine-data.json index 63807ae9b..3faf38591 100644 --- a/wger/manager/fixtures/test-routine-data.json +++ b/wger/manager/fixtures/test-routine-data.json @@ -40,7 +40,7 @@ "model": "manager.day", "fields": { "routine": 1, - "next_day": 2, + "order": 2, "is_rest": false } }, @@ -49,7 +49,7 @@ "model": "manager.day", "fields": { "routine": 1, - "next_day": 3, + "order": 3, "is_rest": false } }, @@ -58,7 +58,7 @@ "model": "manager.day", "fields": { "routine": 1, - "next_day": 1, + "order": 1, "is_rest": false } }, diff --git a/wger/manager/management/commands/dummy-generator-routines.py b/wger/manager/management/commands/dummy-generator-routines.py index 82ae322ac..7b8aed556 100644 --- a/wger/manager/management/commands/dummy-generator-routines.py +++ b/wger/manager/management/commands/dummy-generator-routines.py @@ -35,6 +35,7 @@ from wger.manager.models import ( ) from wger.manager.models.abstract_config import OperationChoices + logger = logging.getLogger(__name__) @@ -89,27 +90,12 @@ class Command(BaseCommand): nr_of_days = random.randint(2, 5) day_list = [] - is_first_day = False - for _ in range(nr_of_days): + for i in range(nr_of_days): uid = str(uuid.uuid4()).split('-') - day = Day(routine=routine, name=f'Dummy day - {uid[0]}') + day = Day(routine=routine, name=f'Dummy day - {uid[0]}', order=i) day.save() - if is_first_day: - routine.first_day = day - routine.save() - - is_first_day = False day_list.append(day) - next_day = None - for day in reversed(day_list): - if next_day: - day.next_day = next_day - day.save() - next_day = day - day_list[-1].next_day = day_list[0] - day_list[-1].save() - # Add exercises (no supersets, all very simple) exercise_list = [i for i in Exercise.objects.all()] for day in day_list: diff --git a/wger/manager/migrations/0018_flexible_routines.py b/wger/manager/migrations/0018_flexible_routines.py index 27404989f..d4a33d650 100644 --- a/wger/manager/migrations/0018_flexible_routines.py +++ b/wger/manager/migrations/0018_flexible_routines.py @@ -50,15 +50,7 @@ class Migration(migrations.Migration): ('is_rest', models.BooleanField(default=False)), ('last_day_in_week', models.BooleanField(default=False)), ('need_logs_to_advance', models.BooleanField(default=False)), - ( - 'next_day', - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - to='manager.dayng', - ), - ), + ('order', models.PositiveIntegerField(default=1, verbose_name='Order')), ], ), migrations.AddField( @@ -98,7 +90,7 @@ class Migration(migrations.Migration): verbose_name='ID', ), ), - ('order', models.IntegerField(default=1, verbose_name='Order')), + ('order', models.PositiveIntegerField(default=1, verbose_name='Order')), ('comment', models.CharField(blank=True, max_length=200, verbose_name='Comment')), ( 'day', @@ -231,15 +223,6 @@ class Migration(migrations.Migration): ), ('start', models.DateField(verbose_name='Start date')), ('end', models.DateField(verbose_name='End date')), - ( - 'first_day', - models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name='first_days', - to='manager.dayng', - ), - ), ( 'user', models.ForeignKey( diff --git a/wger/manager/migrations/0019_flexible_routines_migration.py b/wger/manager/migrations/0019_flexible_routines_migration.py index 1c997f3e2..72ce48353 100644 --- a/wger/manager/migrations/0019_flexible_routines_migration.py +++ b/wger/manager/migrations/0019_flexible_routines_migration.py @@ -53,19 +53,13 @@ def migrate_routines(apps) -> dict[int, Any]: # To simulate a hard coded week, we will create exactly seven day entries (since # we know the routine starts on a monday). for i in range(1, 8): - current_day = DayNg(routine=routine, next_day=None, is_rest=True) + current_day = DayNg(routine=routine, order=i, is_rest=True) current_day.save() day_dict[i] = current_day for i in range(1, 8): current_day = day_dict[i] - if i == 7: - current_day.next_day = day_dict[1] - else: - current_day.next_day = day_dict[i + 1] - current_day.save() - day = workout.day_set.filter(day__id=i).first() if day: current_day.name = day.description if len(day.description) <= 50 else f'Day {i}' diff --git a/wger/manager/models/abstract_config.py b/wger/manager/models/abstract_config.py index 83ce32f70..b3a0ac229 100644 --- a/wger/manager/models/abstract_config.py +++ b/wger/manager/models/abstract_config.py @@ -17,6 +17,7 @@ # Django from django.db import models +# wger from wger.utils.context_processor import processor diff --git a/wger/manager/models/day.py b/wger/manager/models/day.py index 8d86096d9..4ce1cb4df 100644 --- a/wger/manager/models/day.py +++ b/wger/manager/models/day.py @@ -43,6 +43,11 @@ class Day(models.Model): Model for a training day """ + class Meta: + ordering = [ + 'order', + ] + routine = models.ForeignKey( 'Routine', verbose_name=_('Routine'), @@ -50,11 +55,10 @@ class Day(models.Model): related_name='days', ) - next_day = models.ForeignKey( - 'self', - blank=True, - null=True, - on_delete=models.CASCADE, + order = models.PositiveIntegerField( + default=1, + null=False, + verbose_name=_('Order'), ) type = models.CharField( diff --git a/wger/manager/models/routine.py b/wger/manager/models/routine.py index 2bd312cc0..663ded97c 100644 --- a/wger/manager/models/routine.py +++ b/wger/manager/models/routine.py @@ -50,13 +50,6 @@ class Routine(models.Model): on_delete=models.CASCADE, ) - first_day = models.ForeignKey( - 'Day', - on_delete=models.CASCADE, - null=True, - related_name='first_days', - ) - name = models.CharField( verbose_name=_('Name'), max_length=50, @@ -137,15 +130,7 @@ class Routine(models.Model): Each day object points to the next one in the sequence till it loops back """ - - out = [] - day = self.first_day - while day: - if day in out: - break - out.append(day) - day = day.next_day - return out + return list(self.days.all()) @property def label_dict(self) -> dict[datetime.date, str]: @@ -169,7 +154,9 @@ class Routine(models.Model): labels = self.label_dict delta = datetime.timedelta(days=1) current_date = self.start - current_day = self.first_day + days = list(self.days.all()) + current_day = self.days.first() + nr_days = self.days.count() counter = Counter() skip_til_date = None @@ -178,6 +165,7 @@ class Routine(models.Model): if current_day is None: return out + index = 0 while current_date <= self.end: # Fill all days till the end of the week with empty workout days if skip_til_date: @@ -195,6 +183,7 @@ class Routine(models.Model): continue counter[current_day] += 1 + index = (index + 1) % nr_days if current_day.last_day_in_week: days_til_monday = 7 - current_date.weekday() @@ -210,7 +199,7 @@ class Routine(models.Model): ) if current_day.can_proceed(current_date): - current_day = current_day.next_day + current_day = days[index] current_date += delta diff --git a/wger/manager/models/slot.py b/wger/manager/models/slot.py index ccaddb54e..aa2aaad68 100644 --- a/wger/manager/models/slot.py +++ b/wger/manager/models/slot.py @@ -28,7 +28,7 @@ class Slot(models.Model): related_name='slots', ) - order = models.IntegerField( + order = models.PositiveIntegerField( default=1, null=False, verbose_name=_('Order'), diff --git a/wger/manager/tests/test_routine.py b/wger/manager/tests/test_routine.py index 1356970f3..5ee830c2d 100644 --- a/wger/manager/tests/test_routine.py +++ b/wger/manager/tests/test_routine.py @@ -49,30 +49,20 @@ class RoutineTestCase(WgerTestCase): ) self.routine.save() - self.day1 = Day(routine=self.routine, description='day 1') + self.day1 = Day(routine=self.routine, description='day 1', order=1) self.day1.save() self.day2 = Day( routine=self.routine, description='day 2', + order=2, is_rest=True, ) self.day2.save() - self.day3 = Day(routine=self.routine, description='day 3') + self.day3 = Day(routine=self.routine, description='day 3', order=3) self.day3.save() - self.day1.next_day = self.day2 - self.day1.save() - - self.day2.next_day = self.day3 - self.day2.save() - - self.day3.next_day = self.day1 - self.day3.save() - - self.routine.first_day = self.day1 - Label(routine=self.routine, start_offset=0, end_offset=3, label='First label').save() Label(routine=self.routine, start_offset=4, end_offset=5, label='Second label').save()