Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vbos/datasets/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]


Expand Down
Original file line number Diff line number Diff line change
@@ -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,
),
),
]
12 changes: 9 additions & 3 deletions vbos/datasets/models.py
Original file line number Diff line number Diff line change
@@ -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/"

Expand Down Expand Up @@ -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}"
Expand Down
3 changes: 1 addition & 2 deletions vbos/datasets/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -48,7 +47,7 @@ class Meta:
"cluster",
"type",
"source",
"file",
"filename_id",
]


Expand Down
25 changes: 7 additions & 18 deletions vbos/datasets/test/test_models.py
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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):
Expand All @@ -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)
Expand All @@ -75,28 +64,28 @@ 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):
RasterDataset.objects.create(
name="Population",
cluster=self.cluster,
source="Government",
file=r_2,
filename_id="population_baseline",
)


Expand Down
14 changes: 4 additions & 10 deletions vbos/datasets/test/test_raster_views.py
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
Expand Down