Skip to content

Commit 9410a27

Browse files
committed
Change unique name restriction on dataset models
1 parent e35f52b commit 9410a27

File tree

4 files changed

+177
-64
lines changed

4 files changed

+177
-64
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Generated by Django 5.2.5 on 2025-10-09 12:30
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("datasets", "0012_tabulardataset_unit"),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name="rasterdataset",
15+
name="name",
16+
field=models.CharField(max_length=155),
17+
),
18+
migrations.AlterField(
19+
model_name="tabulardataset",
20+
name="name",
21+
field=models.CharField(max_length=155),
22+
),
23+
migrations.AlterField(
24+
model_name="vectordataset",
25+
name="name",
26+
field=models.CharField(max_length=155),
27+
),
28+
migrations.AlterUniqueTogether(
29+
name="rasterdataset",
30+
unique_together={("name", "type")},
31+
),
32+
migrations.AlterUniqueTogether(
33+
name="tabulardataset",
34+
unique_together={("name", "type")},
35+
),
36+
migrations.AlterUniqueTogether(
37+
name="vectordataset",
38+
unique_together={("name", "type")},
39+
),
40+
]

vbos/datasets/models.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def delete_raster_file(sender, instance, **kwargs):
8181

8282

8383
class RasterDataset(models.Model):
84-
name = models.CharField(max_length=155, unique=True)
84+
name = models.CharField(max_length=155)
8585
created = models.DateTimeField(auto_now_add=True)
8686
updated = models.DateTimeField(auto_now=True)
8787
cluster = models.ForeignKey(
@@ -97,10 +97,11 @@ def __str__(self):
9797

9898
class Meta:
9999
ordering = ["id"]
100+
unique_together = ["name", "type"]
100101

101102

102103
class VectorDataset(models.Model):
103-
name = models.CharField(max_length=155, unique=True)
104+
name = models.CharField(max_length=155, unique=False)
104105
created = models.DateTimeField(auto_now_add=True)
105106
updated = models.DateTimeField(auto_now=True)
106107
cluster = models.ForeignKey(
@@ -115,6 +116,7 @@ def __str__(self):
115116

116117
class Meta:
117118
ordering = ["id"]
119+
unique_together = ["name", "type"]
118120

119121

120122
class VectorItem(models.Model):
@@ -138,7 +140,7 @@ class Meta:
138140

139141

140142
class TabularDataset(models.Model):
141-
name = models.CharField(max_length=155, unique=True)
143+
name = models.CharField(max_length=155, unique=False)
142144
created = models.DateTimeField(auto_now_add=True)
143145
updated = models.DateTimeField(auto_now=True)
144146
cluster = models.ForeignKey(
@@ -154,6 +156,7 @@ def __str__(self):
154156

155157
class Meta:
156158
ordering = ["id"]
159+
unique_together = ["name", "type"]
157160

158161

159162
class TabularItem(models.Model):

vbos/datasets/test/test_models.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
from django.db.models.deletion import ProtectedError
2+
from django.db.utils import IntegrityError
3+
from django.test import TestCase
4+
from django.core.files.uploadedfile import SimpleUploadedFile
5+
from django.core.exceptions import ValidationError
6+
7+
from vbos.datasets.models import Cluster, RasterDataset, RasterFile, TabularDataset, VectorDataset
8+
9+
10+
class TestRasterModels(TestCase):
11+
def setUp(self):
12+
self.valid_file = SimpleUploadedFile(
13+
"rainfall.tiff", b"file_content", content_type="image/tiff"
14+
)
15+
self.r_1 = RasterFile.objects.create(name="Rainfall COG", file=self.valid_file)
16+
self.r_2 = RasterFile.objects.create(
17+
name="Coastline COG", file="raster/coastline.tiff"
18+
)
19+
self.dataset = RasterDataset.objects.create(
20+
name="Rainfall",
21+
cluster=Cluster.objects.create(name="Environment"),
22+
file=self.r_1,
23+
)
24+
25+
def test_deletion(self):
26+
# RasterFile can't be deleted if it's associates with a dataset
27+
with self.assertRaises(ProtectedError):
28+
self.r_1.delete()
29+
30+
# name should be unique
31+
raster = RasterFile(name="Rainfall COG 2", file="raster/coastline.tiff")
32+
with self.assertRaises(ValidationError):
33+
raster.full_clean()
34+
35+
# file path should be unique
36+
raster = RasterFile(name="Rainfall COG", file="newfile.tif")
37+
with self.assertRaises(ValidationError):
38+
raster.full_clean()
39+
40+
# modify dataset
41+
self.dataset.file = self.r_2
42+
self.dataset.save()
43+
# delete file
44+
self.r_1.delete()
45+
self.assertEqual(RasterFile.objects.count(), 1)
46+
# delete dataset
47+
self.dataset.delete()
48+
self.assertEqual(RasterDataset.objects.count(), 0)
49+
# delete remaining file
50+
self.r_2.delete()
51+
self.assertEqual(RasterFile.objects.count(), 0)
52+
53+
# test file extension validation
54+
invalid_file = SimpleUploadedFile(
55+
"test.jpg", b"file_content", content_type="image/jpeg"
56+
)
57+
raster = RasterFile(name="Test", file=invalid_file)
58+
with self.assertRaises(ValidationError):
59+
raster.full_clean()
60+
61+
RasterFile.objects.all().delete()
62+
63+
def test_unique_name_type(self):
64+
self.cluster = Cluster.objects.create(name="Administrative")
65+
r_2 = RasterFile.objects.create(
66+
name="Population Density COG", file="raster/pop.tiff"
67+
)
68+
RasterDataset.objects.create(
69+
name="Population",
70+
cluster=self.cluster,
71+
source="Government",
72+
file=r_2,
73+
)
74+
RasterDataset.objects.create(
75+
name="Population",
76+
cluster=self.cluster,
77+
source="Government",
78+
file=r_2,
79+
type="estimated_damage"
80+
)
81+
with self.assertRaises(IntegrityError):
82+
RasterDataset.objects.create(
83+
name="Population",
84+
cluster=self.cluster,
85+
source="Government",
86+
file=r_2,
87+
)
88+
89+
90+
class TestTabularDatasetModel(TestCase):
91+
def test_unique_name_type(self):
92+
self.cluster = Cluster.objects.create(name="Administrative")
93+
TabularDataset.objects.create(
94+
name="Population",
95+
cluster=self.cluster,
96+
source="Government",
97+
)
98+
TabularDataset.objects.create(
99+
name="Population",
100+
cluster=self.cluster,
101+
source="Government",
102+
type="estimated_damage"
103+
)
104+
with self.assertRaises(IntegrityError):
105+
TabularDataset.objects.create(
106+
name="Population",
107+
cluster=self.cluster,
108+
source="Government",
109+
)
110+
111+
112+
class TestVectorDatasetModel(TestCase):
113+
def test_unique_name_type(self):
114+
self.cluster = Cluster.objects.create(name="Administrative")
115+
VectorDataset.objects.create(
116+
name="Population",
117+
cluster=self.cluster,
118+
source="Government",
119+
)
120+
VectorDataset.objects.create(
121+
name="Population",
122+
cluster=self.cluster,
123+
source="Government",
124+
type="estimated_damage"
125+
)
126+
with self.assertRaises(IntegrityError):
127+
VectorDataset.objects.create(
128+
name="Population",
129+
cluster=self.cluster,
130+
source="Government",
131+
)

vbos/datasets/test/test_raster_models.py

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)