diff --git a/fixtures/sample/licensetype.json b/fixtures/sample/license.json similarity index 60% rename from fixtures/sample/licensetype.json rename to fixtures/sample/license.json index 93d21d5b035e83a694332b0fb35afb1cf4044249..c2a270e42dcf380006dd45dd95b728887c642dfe 100644 --- a/fixtures/sample/licensetype.json +++ b/fixtures/sample/license.json @@ -1,66 +1,66 @@ [ { - "model": "program.licensetype", + "model": "program.license", "pk": 1, "fields": { "name": "Public Domain", - "type": "cc-0" + "identifier": "cc-0" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 2, "fields": { "name": "Creative Commons Attribution", - "type": "cc-by" + "identifier": "cc-by" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 3, "fields": { "name": "Creative Commons Attribution-ShareAlike", - "type": "cc-by-sa" + "identifier": "cc-by-sa" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 4, "fields": { "name": "Creative Commons Attribution-NonCommercial", - "type": "cc-by-nc" + "identifier": "cc-by-nc" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 5, "fields": { "name": "Creative Commons Attribution-NonCommercial-ShareAlike", - "type": "cc-by-nc-sa" + "identifier": "cc-by-nc-sa" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 6, "fields": { "name": "Creative Commons Attribution-NoDerivatives", - "type": "cc-by-nd" + "identifier": "cc-by-nd" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 7, "fields": { "name": "Creative Commons Attribution-NonCommercial-NoDerivatives", - "type": "cc-by-nc-nd" + "identifier": "cc-by-nc-nd" } }, { - "model": "program.licensetype", + "model": "program.license", "pk": 8, "fields": { "name": "All Rights Reserved", - "type": "all-rights-reserved" + "identifier": "all-rights-reserved" } } ] \ No newline at end of file diff --git a/program/admin.py b/program/admin.py index 7a20f369e40613a9315d0413bac54354c2c80a73..d936450b8adb936b7d0aaea4062f8a526eed03e4 100644 --- a/program/admin.py +++ b/program/admin.py @@ -6,7 +6,7 @@ from program.models import ( FundingCategory, Host, Language, - LicenseType, + License, LinkType, MusicFocus, RRule, @@ -22,11 +22,16 @@ class AdminWithNameSlugIsActive(admin.ModelAdmin): list_display = ("name", "slug", "is_active") -@admin.register(LicenseType, LinkType) -class AdminWithNameType(admin.ModelAdmin): +@admin.register(LinkType) +class LinkTypeAdmin(admin.ModelAdmin): list_display = ("name", "type") +@admin.register(License) +class LicenseAdmin(admin.ModelAdmin): + list_display = ("name", "identifier") + + @admin.register(Host) class HostAdmin(admin.ModelAdmin): fields = ("name", "email", "biography", "created_at", "created_by", "updated_at", "updated_by") diff --git a/program/migrations/0066_license_delete_licensetype.py b/program/migrations/0066_license_delete_licensetype.py new file mode 100644 index 0000000000000000000000000000000000000000..540105d315ac2570352fc3f9d5a6e2a62485e8a8 --- /dev/null +++ b/program/migrations/0066_license_delete_licensetype.py @@ -0,0 +1,34 @@ +# Generated by Django 4.2.2 on 2023-07-27 19:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("program", "0065_remove_timeslot_note_id_remove_timeslot_show"), + ] + + operations = [ + migrations.CreateModel( + name="License", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("name", models.CharField(help_text="Name of the license", max_length=64)), + ( + "identifier", + models.CharField(help_text="Identifier of the license", max_length=32), + ), + ], + options={ + "ordering": ("name",), + }, + ), + migrations.DeleteModel( + name="LicenseType", + ), + ] diff --git a/program/migrations/0067_image_license.py b/program/migrations/0067_image_license.py new file mode 100644 index 0000000000000000000000000000000000000000..4416ef6a39f12679762f8b76df305e96fb139a97 --- /dev/null +++ b/program/migrations/0067_image_license.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.2 on 2023-07-27 19:23 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("program", "0066_license_delete_licensetype"), + ] + + operations = [ + migrations.AddField( + model_name="image", + name="license", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="images", + to="program.license", + ), + ), + ] diff --git a/program/models.py b/program/models.py index f9d9e0bf23f6e66b7f1a2197629897f20c527ec0..c59a7d5d38cd68499cc6bbb20a055e4e501cef1e 100644 --- a/program/models.py +++ b/program/models.py @@ -113,6 +113,17 @@ class Language(models.Model): return self.name +class License(models.Model): + name = models.CharField(max_length=64, help_text="Name of the license") + identifier = models.CharField(max_length=32, help_text="Identifier of the license") + + class Meta: + ordering = ("name",) + + def __str__(self): + return self.identifier + + class Image(models.Model): alt_text = models.TextField(blank=True, default="") credits = models.TextField(blank=True, default="") @@ -125,6 +136,9 @@ class Image(models.Model): upload_to="images", width_field="width", ) + license = models.ForeignKey( + License, null=True, on_delete=models.SET_NULL, related_name="images" + ) owner = models.CharField(max_length=150) ppoi = PPOIField() width = models.PositiveIntegerField(blank=True, null=True) @@ -187,17 +201,6 @@ class HostLink(Link): host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name="links") -class LicenseType(models.Model): - name = models.CharField(max_length=64, help_text="Name of the license type") - type = models.CharField(max_length=32, help_text="Type of the license") - - class Meta: - ordering = ("name",) - - def __str__(self): - return self.type - - class Show(models.Model): category = models.ManyToManyField(Category, blank=True, related_name="shows") cba_series_id = models.IntegerField(blank=True, null=True) diff --git a/program/serializers.py b/program/serializers.py index eadc158d333c20b5f00ae9abdb44bbceefbf2ae8..88560cfb1d45755809069bb7f529c5694f99973c 100644 --- a/program/serializers.py +++ b/program/serializers.py @@ -33,7 +33,7 @@ from program.models import ( HostLink, Image, Language, - LicenseType, + License, LinkType, MusicFocus, Note, @@ -185,10 +185,10 @@ class LinkTypeSerializer(serializers.ModelSerializer): fields = ("name", "type") -class LicenseTypeSerializer(serializers.ModelSerializer): +class LicenseSerializer(serializers.ModelSerializer): class Meta: - model = LicenseType - fields = ("name", "type") + model = License + fields = ("id", "name", "identifier") class HostLinkSerializer(serializers.ModelSerializer): @@ -220,6 +220,9 @@ class Thumbnail(TypedDict): class ImageSerializer(serializers.ModelSerializer): + license_id = serializers.PrimaryKeyRelatedField( + allow_null=True, queryset=License.objects.all(), required=False, source="license" + ) ppoi = PPOIField(required=False) thumbnails = serializers.SerializerMethodField() @@ -253,6 +256,7 @@ class ImageSerializer(serializers.ModelSerializer): "alt_text", "credits", "image", + "license_id", "ppoi", ) + read_only_fields @@ -273,6 +277,7 @@ class ImageSerializer(serializers.ModelSerializer): instance.alt_text = validated_data.get("alt_text", instance.alt_text) instance.credits = validated_data.get("credits", instance.credits) instance.image.ppoi = validated_data.get("ppoi", instance.ppoi) + instance.license = validated_data.get("license", instance.license) instance.save() diff --git a/program/views.py b/program/views.py index 455ece82e40dd039a849ad7ba4a2f1d9b0de72cb..b16a762ef404b0f8ad340bf204c5c85a0c134550 100644 --- a/program/views.py +++ b/program/views.py @@ -43,7 +43,7 @@ from program.models import ( Host, Image, Language, - LicenseType, + License, LinkType, MusicFocus, Note, @@ -62,7 +62,7 @@ from program.serializers import ( HostSerializer, ImageSerializer, LanguageSerializer, - LicenseTypeSerializer, + LicenseSerializer, LinkTypeSerializer, MusicFocusSerializer, NoteSerializer, @@ -1040,6 +1040,6 @@ class APILinkTypeViewSet(viewsets.ModelViewSet): destroy=extend_schema(summary="Delete an existing license type."), list=extend_schema(summary="List all license types."), ) -class APILicenseTypeViewSet(viewsets.ModelViewSet): - queryset = LicenseType.objects.all() - serializer_class = LicenseTypeSerializer +class APILicenseViewSet(viewsets.ModelViewSet): + queryset = License.objects.all() + serializer_class = LicenseSerializer diff --git a/steering/urls.py b/steering/urls.py index 70df93704acabc6716f9789ba03adba5a8f0155e..a171bea7214497908c022d74083396ecc2d07623 100644 --- a/steering/urls.py +++ b/steering/urls.py @@ -31,7 +31,7 @@ from program.views import ( APIHostViewSet, APIImageViewSet, APILanguageViewSet, - APILicenseTypeViewSet, + APILicenseViewSet, APILinkTypeViewSet, APIMusicFocusViewSet, APINoteViewSet, @@ -61,7 +61,7 @@ router.register(r"types", APITypeViewSet) router.register(r"music-focus", APIMusicFocusViewSet) router.register(r"funding-categories", APIFundingCategoryViewSet) router.register(r"languages", APILanguageViewSet) -router.register(r"license-types", APILicenseTypeViewSet) +router.register(r"licenses", APILicenseViewSet) router.register(r"link-types", APILinkTypeViewSet) router.register(r"rrules", APIRRuleViewSet) router.register(r"images", APIImageViewSet)