Skip to content

Commit

Permalink
10348 add decimal custom field
Browse files Browse the repository at this point in the history
  • Loading branch information
arthanson authored and jeremystretch committed Sep 26, 2022
1 parent 5407d06 commit d80abd5
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 12 deletions.
21 changes: 12 additions & 9 deletions netbox/extras/models/customfields.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
from datetime import datetime, date
import decimal

import django_filters
from django import forms
Expand Down Expand Up @@ -488,7 +489,7 @@ def validate(self, value):
raise ValidationError(f"Value must match regex '{self.validation_regex}'")

# Validate integer
if self.type == CustomFieldTypeChoices.TYPE_INTEGER:
elif self.type == CustomFieldTypeChoices.TYPE_INTEGER:
if type(value) is not int:
raise ValidationError("Value must be an integer.")
if self.validation_minimum is not None and value < self.validation_minimum:
Expand All @@ -497,35 +498,37 @@ def validate(self, value):
raise ValidationError(f"Value must not exceed {self.validation_maximum}")

# Validate decimal
if self.type == CustomFieldTypeChoices.TYPE_DECIMAL:
if type(value) is not str:
elif self.type == CustomFieldTypeChoices.TYPE_DECIMAL:
if type(value) is not decimal.Decimal:
raise ValidationError("Value must be a decimal.")
if self.validation_minimum is not None and value < self.validation_minimum:

converted = decimal.Decimal(value)
if self.validation_minimum is not None and converted < self.validation_minimum:
raise ValidationError(f"Value must be at least {self.validation_minimum}")
if self.validation_maximum is not None and value > self.validation_maximum:
if self.validation_maximum is not None and converted > self.validation_maximum:
raise ValidationError(f"Value must not exceed {self.validation_maximum}")

# Validate boolean
if self.type == CustomFieldTypeChoices.TYPE_BOOLEAN and value not in [True, False, 1, 0]:
elif self.type == CustomFieldTypeChoices.TYPE_BOOLEAN and value not in [True, False, 1, 0]:
raise ValidationError("Value must be true or false.")

# Validate date
if self.type == CustomFieldTypeChoices.TYPE_DATE:
elif self.type == CustomFieldTypeChoices.TYPE_DATE:
if type(value) is not date:
try:
datetime.strptime(value, '%Y-%m-%d')
except ValueError:
raise ValidationError("Date values must be in the format YYYY-MM-DD.")

# Validate selected choice
if self.type == CustomFieldTypeChoices.TYPE_SELECT:
elif self.type == CustomFieldTypeChoices.TYPE_SELECT:
if value not in self.choices:
raise ValidationError(
f"Invalid choice ({value}). Available choices are: {', '.join(self.choices)}"
)

# Validate all selected choices
if self.type == CustomFieldTypeChoices.TYPE_MULTISELECT:
elif self.type == CustomFieldTypeChoices.TYPE_MULTISELECT:
if not set(value).issubset(self.choices):
raise ValidationError(
f"Invalid choice(s) ({', '.join(value)}). Available choices are: {', '.join(self.choices)}"
Expand Down
6 changes: 3 additions & 3 deletions netbox/extras/tests/test_customfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def test_get_custom_fields(self):
CustomFieldTypeChoices.TYPE_MULTISELECT: 'array',
CustomFieldTypeChoices.TYPE_OBJECT: 'object',
CustomFieldTypeChoices.TYPE_MULTIOBJECT: 'array',
CustomFieldTypeChoices.TYPE_DECIMAL: 'decimal',
CustomFieldTypeChoices.TYPE_git: 'decimal',
}

self.add_permissions('extras.view_customfield')
Expand Down Expand Up @@ -1201,8 +1201,8 @@ def test_filter_integer(self):
self.assertEqual(self.filterset({'cf_cf1__lte': [200]}, self.queryset).qs.count(), 2)

def test_filter_decimal(self):
self.assertEqual(self.filterset({'cf_cf12': [100.25, 200.25]}, self.queryset).qs.count(), 2)
self.assertEqual(self.filterset({'cf_cf12__n': [200.25]}, self.queryset).qs.count(), 2)
self.assertEqual(self.filterset({'cf_cf12': [100.25, 200.25]}, self.queryset).qs.count(), 3)
self.assertEqual(self.filterset({'cf_cf12__n': [200.25]}, self.queryset).qs.count(), 3)
self.assertEqual(self.filterset({'cf_cf12__gt': [200.25]}, self.queryset).qs.count(), 1)
self.assertEqual(self.filterset({'cf_cf12__gte': [200.25]}, self.queryset).qs.count(), 2)
self.assertEqual(self.filterset({'cf_cf12__lt': [200.25]}, self.queryset).qs.count(), 1)
Expand Down

0 comments on commit d80abd5

Please sign in to comment.