mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-24 08:25:17 -06:00
10348 add decimal custom field
This commit is contained in:
parent
64acd5f957
commit
5a389cde1f
@ -438,7 +438,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
|||||||
|
|
||||||
# Decimal
|
# Decimal
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_DECIMAL:
|
elif self.type == CustomFieldTypeChoices.TYPE_DECIMAL:
|
||||||
filter_class = filters.MultiValueNumberFilter
|
filter_class = filters.MultiValueDecimalFilter
|
||||||
|
|
||||||
# Boolean
|
# Boolean
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_BOOLEAN:
|
elif self.type == CustomFieldTypeChoices.TYPE_BOOLEAN:
|
||||||
@ -499,7 +499,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
|||||||
|
|
||||||
# Validate decimal
|
# Validate decimal
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_DECIMAL:
|
elif self.type == CustomFieldTypeChoices.TYPE_DECIMAL:
|
||||||
if type(value) is not decimal.Decimal:
|
if type(value) is not decimal.Decimal and type(value) is not str:
|
||||||
raise ValidationError("Value must be a decimal.")
|
raise ValidationError("Value must be a decimal.")
|
||||||
|
|
||||||
converted = decimal.Decimal(value)
|
converted = decimal.Decimal(value)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import decimal
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -459,7 +460,7 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
custom_fields[8].name: ['Bar', 'Baz'],
|
custom_fields[8].name: ['Bar', 'Baz'],
|
||||||
custom_fields[9].name: vlans[1].pk,
|
custom_fields[9].name: vlans[1].pk,
|
||||||
custom_fields[10].name: [vlans[2].pk, vlans[3].pk],
|
custom_fields[10].name: [vlans[2].pk, vlans[3].pk],
|
||||||
custom_fields[11].name: 456.78,
|
custom_fields[11].name: '456.78',
|
||||||
}
|
}
|
||||||
sites[1].save()
|
sites[1].save()
|
||||||
|
|
||||||
@ -476,7 +477,7 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
CustomFieldTypeChoices.TYPE_MULTISELECT: 'array',
|
CustomFieldTypeChoices.TYPE_MULTISELECT: 'array',
|
||||||
CustomFieldTypeChoices.TYPE_OBJECT: 'object',
|
CustomFieldTypeChoices.TYPE_OBJECT: 'object',
|
||||||
CustomFieldTypeChoices.TYPE_MULTIOBJECT: 'array',
|
CustomFieldTypeChoices.TYPE_MULTIOBJECT: 'array',
|
||||||
CustomFieldTypeChoices.TYPE_git: 'decimal',
|
CustomFieldTypeChoices.TYPE_DECIMAL: 'decimal',
|
||||||
}
|
}
|
||||||
|
|
||||||
self.add_permissions('extras.view_customfield')
|
self.add_permissions('extras.view_customfield')
|
||||||
@ -610,7 +611,7 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
'multiselect_field': ['Bar', 'Baz'],
|
'multiselect_field': ['Bar', 'Baz'],
|
||||||
'object_field': VLAN.objects.get(vid=2).pk,
|
'object_field': VLAN.objects.get(vid=2).pk,
|
||||||
'multiobject_field': list(VLAN.objects.filter(vid__in=[3, 4]).values_list('pk', flat=True)),
|
'multiobject_field': list(VLAN.objects.filter(vid__in=[3, 4]).values_list('pk', flat=True)),
|
||||||
'decimal_field': 456.78,
|
'decimal_field': '456.78',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
url = reverse('dcim-api:site-list')
|
url = reverse('dcim-api:site-list')
|
||||||
@ -733,7 +734,7 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
'multiselect_field': ['Bar', 'Baz'],
|
'multiselect_field': ['Bar', 'Baz'],
|
||||||
'object_field': VLAN.objects.get(vid=2).pk,
|
'object_field': VLAN.objects.get(vid=2).pk,
|
||||||
'multiobject_field': list(VLAN.objects.filter(vid__in=[3, 4]).values_list('pk', flat=True)),
|
'multiobject_field': list(VLAN.objects.filter(vid__in=[3, 4]).values_list('pk', flat=True)),
|
||||||
'decimal_field': 456.78,
|
'decimal_field': '456.78',
|
||||||
}
|
}
|
||||||
data = (
|
data = (
|
||||||
{
|
{
|
||||||
@ -829,7 +830,7 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
[obj['id'] for obj in response_cf['multiobject_field']],
|
[obj['id'] for obj in response_cf['multiobject_field']],
|
||||||
original_cfvs['multiobject_field']
|
original_cfvs['multiobject_field']
|
||||||
)
|
)
|
||||||
self.assertEqual(response_cf['decimal_field'], data['custom_fields']['decimal_field'])
|
self.assertEqual(response_cf['decimal_field'], original_cfvs['decimal_field'])
|
||||||
|
|
||||||
# Validate database data
|
# Validate database data
|
||||||
site2.refresh_from_db()
|
site2.refresh_from_db()
|
||||||
@ -844,7 +845,7 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
self.assertEqual(site2.custom_field_data['multiselect_field'], original_cfvs['multiselect_field'])
|
self.assertEqual(site2.custom_field_data['multiselect_field'], original_cfvs['multiselect_field'])
|
||||||
self.assertEqual(site2.custom_field_data['object_field'], original_cfvs['object_field'])
|
self.assertEqual(site2.custom_field_data['object_field'], original_cfvs['object_field'])
|
||||||
self.assertEqual(site2.custom_field_data['multiobject_field'], original_cfvs['multiobject_field'])
|
self.assertEqual(site2.custom_field_data['multiobject_field'], original_cfvs['multiobject_field'])
|
||||||
self.assertEqual(site2.custom_field_data['decimal_field'], data['custom_fields']['decimal_field'])
|
self.assertEqual(site2.custom_field_data['decimal_field'], original_cfvs['decimal_field'])
|
||||||
|
|
||||||
def test_minimum_maximum_values_validation(self):
|
def test_minimum_maximum_values_validation(self):
|
||||||
site2 = Site.objects.get(name='Site 2')
|
site2 = Site.objects.get(name='Site 2')
|
||||||
|
@ -23,7 +23,7 @@ def multivalue_field_factory(field_class):
|
|||||||
field.to_python(v) for v in value if v
|
field.to_python(v) for v in value if v
|
||||||
]
|
]
|
||||||
|
|
||||||
return type('MultiValue{}'.format(field_class.__name__), (NewField,), dict())
|
return type(f'MultiValue{field_class.__name__}', (NewField,), dict())
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -46,6 +46,10 @@ class MultiValueNumberFilter(django_filters.MultipleChoiceFilter):
|
|||||||
field_class = multivalue_field_factory(forms.IntegerField)
|
field_class = multivalue_field_factory(forms.IntegerField)
|
||||||
|
|
||||||
|
|
||||||
|
class MultiValueDecimalFilter(django_filters.MultipleChoiceFilter):
|
||||||
|
field_class = multivalue_field_factory(forms.DecimalField)
|
||||||
|
|
||||||
|
|
||||||
class MultiValueTimeFilter(django_filters.MultipleChoiceFilter):
|
class MultiValueTimeFilter(django_filters.MultipleChoiceFilter):
|
||||||
field_class = multivalue_field_factory(forms.TimeField)
|
field_class = multivalue_field_factory(forms.TimeField)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user