From fb3b8d2275d836424d32c7ae852d58a3490dc164 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Fri, 14 Nov 2025 16:36:00 -0300 Subject: [PATCH] Remove file from RasterDataset model and add filename_id --- vbos/datasets/admin.py | 2 +- ...rdataset_file_rasterdataset_filename_id.py | 26 +++++++++++++++++++ vbos/datasets/models.py | 12 ++++++--- vbos/datasets/serializers.py | 3 +-- vbos/datasets/test/test_models.py | 25 +++++------------- vbos/datasets/test/test_raster_views.py | 14 +++------- 6 files changed, 48 insertions(+), 34 deletions(-) create mode 100644 vbos/datasets/migrations/0019_remove_rasterdataset_file_rasterdataset_filename_id.py diff --git a/vbos/datasets/admin.py b/vbos/datasets/admin.py index 44563ca..a068e53 100644 --- a/vbos/datasets/admin.py +++ b/vbos/datasets/admin.py @@ -37,7 +37,7 @@ class RasterFileAdmin(admin.ModelAdmin): @admin.register(RasterDataset) class RasterDatasetAdmin(admin.ModelAdmin): - list_display = ["id", "name", "cluster", "type", "updated", "file"] + list_display = ["id", "name", "cluster", "type", "updated", "filename_id"] list_filter = ["cluster", "type"] diff --git a/vbos/datasets/migrations/0019_remove_rasterdataset_file_rasterdataset_filename_id.py b/vbos/datasets/migrations/0019_remove_rasterdataset_file_rasterdataset_filename_id.py new file mode 100644 index 0000000..78d01f3 --- /dev/null +++ b/vbos/datasets/migrations/0019_remove_rasterdataset_file_rasterdataset_filename_id.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.5 on 2025-11-14 19:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("datasets", "0018_auto_20251114_0018"), + ] + + operations = [ + migrations.RemoveField( + model_name="rasterdataset", + name="file", + ), + migrations.AddField( + model_name="rasterdataset", + name="filename_id", + field=models.CharField( + blank=True, + help_text="The filename id that will be used to compose the raster file path. The pattern will be /media//{filename_id}_{year}.vrt", + max_length=50, + ), + ), + ] diff --git a/vbos/datasets/models.py b/vbos/datasets/models.py index 476ffe6..9264dea 100644 --- a/vbos/datasets/models.py +++ b/vbos/datasets/models.py @@ -1,10 +1,10 @@ -from django.contrib.gis.db import models from django.conf import settings -from django.utils.translation import gettext_lazy as _ +from django.contrib.gis.db import models from django.core.validators import FileExtensionValidator from django.db.models.fields.files import default_storage from django.db.models.signals import pre_delete from django.dispatch import receiver +from django.utils.translation import gettext_lazy as _ UPLOAD_TO = "staging/raster/" if settings.DEBUG else "production/raster/" @@ -91,7 +91,13 @@ class RasterDataset(models.Model): ) type = models.CharField(max_length=55, choices=TYPE_CHOICES, default="baseline") source = models.CharField(max_length=155, blank=True, null=True) - file = models.ForeignKey(RasterFile, on_delete=models.PROTECT) + filename_id = models.CharField( + max_length=50, + blank=True, + help_text="The filename id that will be used to compose the raster file path. The pattern will be {}/{}_{}.vrt".format( + settings.MEDIA_URL, "{filename_id}", "{year}" + ), + ) def __str__(self): return f"{self.name} - {self.cluster} / {self.type}" diff --git a/vbos/datasets/serializers.py b/vbos/datasets/serializers.py index f0f8b60..2a24329 100644 --- a/vbos/datasets/serializers.py +++ b/vbos/datasets/serializers.py @@ -34,7 +34,6 @@ class Meta: class RasterDatasetSerializer(serializers.ModelSerializer): - file = serializers.ReadOnlyField(source="file.file.url") cluster = serializers.ReadOnlyField(source="cluster.name") class Meta: @@ -48,7 +47,7 @@ class Meta: "cluster", "type", "source", - "file", + "filename_id", ] diff --git a/vbos/datasets/test/test_models.py b/vbos/datasets/test/test_models.py index 1ca907a..5010f35 100644 --- a/vbos/datasets/test/test_models.py +++ b/vbos/datasets/test/test_models.py @@ -1,8 +1,7 @@ -from django.db.models.deletion import ProtectedError +from django.core.exceptions import ValidationError +from django.core.files.uploadedfile import SimpleUploadedFile from django.db.utils import IntegrityError from django.test import TestCase -from django.core.files.uploadedfile import SimpleUploadedFile -from django.core.exceptions import ValidationError from vbos.datasets.models import ( Cluster, @@ -25,14 +24,10 @@ def setUp(self): self.dataset = RasterDataset.objects.create( name="Rainfall", cluster=Cluster.objects.create(name="Environment"), - file=self.r_1, + filename_id="rainfall", ) def test_deletion(self): - # RasterFile can't be deleted if it's associates with a dataset - with self.assertRaises(ProtectedError): - self.r_1.delete() - # name should be unique raster = RasterFile(name="Rainfall COG 2", file="raster/coastline.tiff") with self.assertRaises(ValidationError): @@ -43,15 +38,9 @@ def test_deletion(self): with self.assertRaises(ValidationError): raster.full_clean() - # modify dataset - self.dataset.file = self.r_2 - self.dataset.save() # delete file self.r_1.delete() self.assertEqual(RasterFile.objects.count(), 1) - # delete dataset - self.dataset.delete() - self.assertEqual(RasterDataset.objects.count(), 0) # delete remaining file self.r_2.delete() self.assertEqual(RasterFile.objects.count(), 0) @@ -75,20 +64,20 @@ def test_unique_name_type_cluster(self): name="Population", cluster=self.cluster, source="Government", - file=r_2, + filename_id="population_baseline", ) RasterDataset.objects.create( name="Population", cluster=self.cluster, source="Government", - file=r_2, + filename_id="population_damage", type="estimated_damage", ) RasterDataset.objects.create( name="Population", cluster=Cluster.objects.create(name="Education"), source="Government", - file=r_2, + filename_id="population_education_damage", type="estimated_damage", ) with self.assertRaises(IntegrityError): @@ -96,7 +85,7 @@ def test_unique_name_type_cluster(self): name="Population", cluster=self.cluster, source="Government", - file=r_2, + filename_id="population_baseline", ) diff --git a/vbos/datasets/test/test_raster_views.py b/vbos/datasets/test/test_raster_views.py index f0c579b..4d6b3c3 100644 --- a/vbos/datasets/test/test_raster_views.py +++ b/vbos/datasets/test/test_raster_views.py @@ -1,28 +1,22 @@ +from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase -from django.urls import reverse from ..models import Cluster, RasterDataset, RasterFile class TestRasterDatasetListDetailViews(APITestCase): def setUp(self): - self.r_1 = RasterFile.objects.create( - name="Rainfall COG", file="raster/rainfall.tiff" - ) - self.r_2 = RasterFile.objects.create( - name="Coastline COG", file="raster/coastline.tiff" - ) self.dataset_1 = RasterDataset.objects.create( name="Rainfall", description="Rainfall data since 2020", cluster=Cluster.objects.create(name="Environment"), - file=self.r_1, + filename_id="rainfall", source="WMO", ) self.dataset_2 = RasterDataset.objects.create( name="Coastline changes", - file=self.r_2, + filename_id="population_baseline", source="OSM", cluster=Cluster.objects.create(name="Administrative"), type="estimated_damage", @@ -64,7 +58,7 @@ def test_raster_datasets_detail(self): req = self.client.get(url) assert req.status_code == status.HTTP_200_OK assert req.data.get("name") == "Rainfall" - assert req.data.get("file") == "/media/raster/rainfall.tiff" + assert req.data.get("filename_id") == "rainfall" assert req.data.get("created") assert req.data.get("updated") assert req.data.get("source") == "WMO"