From 2069dbca2c51a6a17b7e3ccdb6e9c8fb07467942 Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Tue, 12 Nov 2024 12:57:38 -0400
Subject: [PATCH] feat: add validation of the duration for Playlist entries

---
 .../0125_alter_playlistentry_duration.py      | 21 +++++++++++++++++++
 program/models.py                             |  9 +++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)
 create mode 100644 program/migrations/0125_alter_playlistentry_duration.py

diff --git a/program/migrations/0125_alter_playlistentry_duration.py b/program/migrations/0125_alter_playlistentry_duration.py
new file mode 100644
index 00000000..7a2cb148
--- /dev/null
+++ b/program/migrations/0125_alter_playlistentry_duration.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.2.16 on 2024-11-12 16:39
+
+import program.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("program", "0124_alter_playlist_options"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="playlistentry",
+            name="duration",
+            field=models.FloatField(
+                null=True, validators=[program.models.validate_positive_duration]
+            ),
+        ),
+    ]
diff --git a/program/models.py b/program/models.py
index 253e0a05..a3df5d49 100644
--- a/program/models.py
+++ b/program/models.py
@@ -605,8 +605,15 @@ class Playlist(models.Model):
         return f"{self.show.name} - {self.description}" if self.description else self.show.name
 
 
+def validate_positive_duration(value: float) -> None:
+    """Validates that the duration is positive. Raises a Django `ValidationError` if negative."""
+
+    if value < 0.0:
+        raise DjangoValidationError("duration must be positive")
+
+
 class PlaylistEntry(models.Model):
-    duration = models.FloatField(null=True)
+    duration = models.FloatField(null=True, validators=[validate_positive_duration])
     file_id = models.IntegerField(null=True)
     line_num = models.IntegerField(null=False)
     playlist = models.ForeignKey(Playlist, on_delete=models.CASCADE, related_name="entries")
-- 
GitLab