From b7ebee93c61802322aacc048d17b5246d389cec6 Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 21 Sep 2023 08:56:14 -0700 Subject: [PATCH] fix: add migration --- .../0004_soildata_depth_intervals.py | 22 +++++++ .../apps/soil_id/models/soil_data.py | 63 +++++++++---------- 2 files changed, 51 insertions(+), 34 deletions(-) create mode 100644 terraso_backend/apps/soil_id/migrations/0004_soildata_depth_intervals.py diff --git a/terraso_backend/apps/soil_id/migrations/0004_soildata_depth_intervals.py b/terraso_backend/apps/soil_id/migrations/0004_soildata_depth_intervals.py new file mode 100644 index 000000000..4f110f9c7 --- /dev/null +++ b/terraso_backend/apps/soil_id/migrations/0004_soildata_depth_intervals.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.5 on 2023-09-21 15:54 + +import apps.soil_id.models.soil_data +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("soil_id", "0003_alter_depthdependentsoildata_options_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="soildata", + name="depth_intervals", + field=models.JSONField( + blank=True, + default=apps.soil_id.models.soil_data.default_depth_intervals, + validators=[apps.soil_id.models.soil_data.validate_depth_intervals], + ), + ), + ] diff --git a/terraso_backend/apps/soil_id/models/soil_data.py b/terraso_backend/apps/soil_id/models/soil_data.py index d52618cb9..2db728379 100644 --- a/terraso_backend/apps/soil_id/models/soil_data.py +++ b/terraso_backend/apps/soil_id/models/soil_data.py @@ -21,6 +21,34 @@ from apps.project_management.models.sites import Site +def default_depth_intervals(): + return [] + + +def validate_depth_intervals(intervals): + if not isinstance(intervals, list): + raise ValidationError(f"Depth intervals must be list, got {intervals}") + for index, interval in enumerate(intervals): + if not isinstance(interval, dict) or len(interval) != 2: + raise ValidationError(f"Depth interval must be two element dict, got {interval}") + for field in ["start", "end"]: + if field not in interval or not isinstance(interval[field], int): + raise ValidationError( + f"Depth interval {field} must exist and be integer, got {interval[field]}" + ) + if interval["start"] < 0 or interval["end"] > 200: + raise ValidationError(f"Depth interval must be between 0 and 200, got {interval}") + if interval["start"] >= interval["end"]: + raise ValidationError(f"Depth interval start must be less than end, got {interval}") + if index + 1 < len(intervals) and interval["end"] > intervals[index + 1]["start"]: + raise ValidationError( + f""" + Depth interval must end at or before next interval, + got {interval} followed by {intervals[index + 1]} + """ + ) + + class SoilData(BaseModel): site = models.OneToOneField(Site, on_delete=models.CASCADE, related_name="soil_data") @@ -77,39 +105,6 @@ class SlopeSteepness(models.TextChoices): blank=True, null=True, validators=[MinValueValidator(0), MaxValueValidator(90)] ) - @staticmethod - def _depth_interval_validation_error(): - raise ValidationError( - """ - depth intervals must conform to JSON spec [{ start: number, end: number }], - with non-overlapping intervals between 0 and 200 - """ - ) - - @staticmethod - def validate_depth_intervals(intervals): - if not isinstance(intervals, list): - raise ValidationError(f"Depth intervals must be list, got {intervals}") - for index, interval in enumerate(intervals): - if not isinstance(interval, dict) or len(interval) != 2: - raise ValidationError(f"Depth interval must be two element dict, got {interval}") - for field in ["start", "end"]: - if field not in interval or not isinstance(interval[field], int): - raise ValidationError( - f"Depth interval {field} must exist and be integer, got {interval[field]}" - ) - if interval["start"] < 0 or interval["end"] > 200: - raise ValidationError(f"Depth interval must be between 0 and 200, got {interval}") - if interval["start"] >= interval["end"]: - raise ValidationError(f"Depth interval start must be less than end, got {interval}") - if index + 1 < len(intervals) and interval["end"] > intervals[index + 1]["start"]: - raise ValidationError( - f""" - Depth interval must end at or before next interval, - got {interval} followed by {intervals[index + 1]} - """ - ) - depth_intervals = models.JSONField( - blank=True, validators=[validate_depth_intervals], default=lambda: [] + blank=True, validators=[validate_depth_intervals], default=default_depth_intervals )