From 7b76a9c482f60e9b8681542651a159d64a3a5e35 Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Wed, 31 Jan 2024 16:38:37 -0400
Subject: [PATCH] feat: use foreign-key reference for LinkType

Closes: #187
---
 fixtures/sample/linktype.json                 | 39 +++++--------
 program/admin.py                              |  2 +-
 ...nktype_type_linktype_is_active_and_more.py | 55 +++++++++++++++++++
 program/models.py                             |  6 +-
 program/serializers.py                        | 14 +++--
 5 files changed, 82 insertions(+), 34 deletions(-)
 create mode 100644 program/migrations/0078_remove_linktype_type_linktype_is_active_and_more.py

diff --git a/fixtures/sample/linktype.json b/fixtures/sample/linktype.json
index 059627a6..b78e54b9 100644
--- a/fixtures/sample/linktype.json
+++ b/fixtures/sample/linktype.json
@@ -3,104 +3,91 @@
     "model": "program.linktype",
     "pk": 1,
     "fields": {
-      "name": "Website",
-      "type": "website"
+      "name": "Website"
     }
   },
   {
     "model": "program.linktype",
     "pk": 2,
     "fields": {
-      "name": "CBA",
-      "type": "cba"
+      "name": "CBA"
     }
   },
   {
     "model": "program.linktype",
     "pk": 3,
     "fields": {
-      "name": "Freie Radios Online",
-      "type": "freie-radios-online"
+      "name": "Freie Radios Online"
     }
   },
   {
     "model": "program.linktype",
     "pk": 4,
     "fields": {
-      "name": "Funkwhale",
-      "type": "funkwhale"
+      "name": "Funkwhale"
     }
   },
   {
     "model": "program.linktype",
     "pk": 5,
     "fields": {
-      "name": "Mixcloud",
-      "type": "mixcloud"
+      "name": "Mixcloud"
     }
   },
   {
     "model": "program.linktype",
     "pk": 6,
     "fields": {
-      "name": "SoundCloud",
-      "type": "soundcloud"
+      "name": "SoundCloud"
     }
   },
   {
     "model": "program.linktype",
     "pk": 7,
     "fields": {
-      "name": "Internet Archive (archive.org)",
-      "type": "internet-archive"
+      "name": "Internet Archive (archive.org)"
     }
   },
   {
     "model": "program.linktype",
     "pk": 8,
     "fields": {
-      "name": "YouTube",
-      "type": "youTube"
+      "name": "YouTube"
     }
   },
   {
     "model": "program.linktype",
     "pk": 9,
     "fields": {
-      "name": "Spotify",
-      "type": "spotify"
+      "name": "Spotify"
     }
   },
   {
     "model": "program.linktype",
     "pk": 10,
     "fields": {
-      "name": "Instagram",
-      "type": "instagram"
+      "name": "Instagram"
     }
   },
   {
     "model": "program.linktype",
     "pk": 11,
     "fields": {
-      "name": "Facebook",
-      "type": "facebook"
+      "name": "Facebook"
     }
   },
   {
     "model": "program.linktype",
     "pk": 12,
     "fields": {
-      "name": "Twitter",
-      "type": "twitter"
+      "name": "Twitter"
     }
   },
   {
     "model": "program.linktype",
     "pk": 13,
     "fields": {
-      "name": "Mastodon",
-      "type": "mastodon"
+      "name": "Mastodon"
     }
   }
 ]
diff --git a/program/admin.py b/program/admin.py
index d936450b..4dc801a8 100644
--- a/program/admin.py
+++ b/program/admin.py
@@ -24,7 +24,7 @@ class AdminWithNameSlugIsActive(admin.ModelAdmin):
 
 @admin.register(LinkType)
 class LinkTypeAdmin(admin.ModelAdmin):
-    list_display = ("name", "type")
+    list_display = ("name",)
 
 
 @admin.register(License)
diff --git a/program/migrations/0078_remove_linktype_type_linktype_is_active_and_more.py b/program/migrations/0078_remove_linktype_type_linktype_is_active_and_more.py
new file mode 100644
index 00000000..124e927e
--- /dev/null
+++ b/program/migrations/0078_remove_linktype_type_linktype_is_active_and_more.py
@@ -0,0 +1,55 @@
+# Generated by Django 4.2.6 on 2024-01-31 19:53
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("program", "0077_alter_host_options_alter_note_options_and_more"),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name="linktype",
+            name="type",
+        ),
+        migrations.AddField(
+            model_name="linktype",
+            name="is_active",
+            field=models.BooleanField(default=True),
+        ),
+        migrations.RemoveField(
+            model_name="hostlink",
+            name="type",
+        ),
+        migrations.AddField(
+            model_name="hostlink",
+            name="type",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="program.linktype"
+            ),
+        ),
+        migrations.RemoveField(
+            model_name="notelink",
+            name="type",
+        ),
+        migrations.AddField(
+            model_name="notelink",
+            name="type",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="program.linktype"
+            ),
+        ),
+        migrations.RemoveField(
+            model_name="showlink",
+            name="type",
+        ),
+        migrations.AddField(
+            model_name="showlink",
+            name="type",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="program.linktype"
+            ),
+        ),
+    ]
diff --git a/program/models.py b/program/models.py
index 0dc71029..541a434f 100644
--- a/program/models.py
+++ b/program/models.py
@@ -183,18 +183,18 @@ class Host(models.Model):
 
 
 class LinkType(models.Model):
+    is_active = models.BooleanField(default=True)
     name = models.CharField(max_length=32, help_text="Name of the link type")
-    type = models.CharField(max_length=32, help_text="Type of the link")
 
     class Meta:
         ordering = ("name",)
 
     def __str__(self):
-        return self.type
+        return self.name
 
 
 class Link(models.Model):
-    type = models.CharField(max_length=64)
+    type = models.ForeignKey(LinkType, default=1, on_delete=models.CASCADE)
     url = models.URLField()
 
     class Meta:
diff --git a/program/serializers.py b/program/serializers.py
index c349eb22..d5107d0c 100644
--- a/program/serializers.py
+++ b/program/serializers.py
@@ -194,7 +194,7 @@ class CategorySerializer(serializers.ModelSerializer):
 class LinkTypeSerializer(serializers.ModelSerializer):
     class Meta:
         model = LinkType
-        fields = ("id", "name", "type")
+        fields = ("id", "is_active", "name")
 
 
 class LicenseSerializer(serializers.ModelSerializer):
@@ -211,9 +211,11 @@ class LicenseSerializer(serializers.ModelSerializer):
 
 
 class HostLinkSerializer(serializers.ModelSerializer):
+    type_id = serializers.PrimaryKeyRelatedField(queryset=LinkType.objects.all(), source="type")
+
     class Meta:
+        fields = ("type_id", "url")
         model = HostLink
-        fields = ("type", "url")
 
 
 class PPOIField(serializers.CharField):
@@ -450,9 +452,11 @@ class FundingCategorySerializer(serializers.ModelSerializer):
 
 
 class ShowLinkSerializer(serializers.ModelSerializer):
+    type_id = serializers.PrimaryKeyRelatedField(queryset=LinkType.objects.all(), source="type")
+
     class Meta:
         model = ShowLink
-        fields = ("type", "url")
+        fields = ("type_id", "url")
 
 
 class ShowSerializer(serializers.HyperlinkedModelSerializer):
@@ -884,9 +888,11 @@ class TimeSlotSerializer(serializers.ModelSerializer):
 
 
 class NoteLinkSerializer(serializers.ModelSerializer):
+    type_id = serializers.PrimaryKeyRelatedField(queryset=LinkType.objects.all(), source="type")
+
     class Meta:
         model = NoteLink
-        fields = ("type", "url")
+        fields = ("type_id", "url")
 
 
 tags_json_schema = {"type": "array", "items": {"type": "string"}}
-- 
GitLab