diff --git a/tests/models.py b/tests/models.py index 974d097..9b7e77c 100644 --- a/tests/models.py +++ b/tests/models.py @@ -15,6 +15,7 @@ class Profile(models.Model): boolean = models.BooleanField(blank=True, null=True) integer = models.IntegerField(blank=True, null=True) + decimal = models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True) json = models.JSONField(blank=True, null=True) positive_integer = models.PositiveIntegerField(blank=True, null=True) slug = models.SlugField(blank=True, null=True) diff --git a/tests/serializers.py b/tests/serializers.py index 99b6c52..13f6d4f 100644 --- a/tests/serializers.py +++ b/tests/serializers.py @@ -35,6 +35,7 @@ class Meta: "avatar", "boolean", "integer", + "decimal", "json", "positive_integer", "slug", @@ -58,6 +59,7 @@ class Meta: "avatar", "boolean", "integer", + "decimal", "json", "positive_integer", "slug", diff --git a/tests/test_validators.py b/tests/test_validators.py index 76d36a6..0db0f80 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -22,6 +22,7 @@ def profile_view_fixture(db, now, profile_factory, rf): phone=phone, boolean=True, integer=123, + decimal=0.35, json=dict(something=True), positive_integer=123, slug="something", @@ -56,6 +57,7 @@ def test_validate_bundle(profile_view): profile_view.validate_bundle("phone") profile_view.validate_bundle("boolean") profile_view.validate_bundle("integer") + profile_view.validate_bundle("decimal") profile_view.validate_bundle("json") profile_view.validate_bundle("positive_integer") profile_view.validate_bundle("slug") diff --git a/worf/validators.py b/worf/validators.py index 7bba67f..95d43d1 100644 --- a/worf/validators.py +++ b/worf/validators.py @@ -118,6 +118,19 @@ def _validate_positive_int(self, key): ) return integer + + def _validate_decimal(self, key): + value = self.bundle[key] + + if value is None or value == "": + return None + + try: + decimal = float(value) + except (TypeError, ValueError): + raise ValidationError(f"Field {self.keymap[key]} accepts an decimal") + + return decimal ############################################################################ # Public methods for use downstream @@ -227,6 +240,10 @@ def validate_bundle(self, key): # noqa: C901 elif isinstance(field, (models.IntegerField, models.SmallIntegerField)): self.bundle[key] = self._validate_int(key) return + + elif isinstance(field, (models.DecimalField)): + self.bundle[key] = self._validate_decimal(key) + return elif isinstance(field, models.BooleanField): self.bundle[key] = self._validate_boolean(key) @@ -258,7 +275,7 @@ def validate_bundle(self, key): # noqa: C901 return # Django will raise an exception if handled improperly else: # pragma: no cover - message = f"{field.get_internal_type()} has no validation method for {key}" + message = f"{field.get_internal_type()} has no validation method for something like {key}" if settings.WORF_DEBUG: message += f":: Received {self.bundle[key]}" raise NotImplementedError(message)