mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-09 01:49:35 -06:00
Merge pull request #20625 from netbox-community/20498-url-custom-field-validation-regex
Fixes #20498: Apply validation regex to URL custom fields
This commit is contained in:
commit
0b97df0984
@ -535,6 +535,15 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
|||||||
# URL
|
# URL
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_URL:
|
elif self.type == CustomFieldTypeChoices.TYPE_URL:
|
||||||
field = LaxURLField(assume_scheme='https', required=required, initial=initial)
|
field = LaxURLField(assume_scheme='https', required=required, initial=initial)
|
||||||
|
if self.validation_regex:
|
||||||
|
field.validators = [
|
||||||
|
RegexValidator(
|
||||||
|
regex=self.validation_regex,
|
||||||
|
message=mark_safe(_("Values must match this regex: <code>{regex}</code>").format(
|
||||||
|
regex=escape(self.validation_regex)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# JSON
|
# JSON
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_JSON:
|
elif self.type == CustomFieldTypeChoices.TYPE_JSON:
|
||||||
@ -684,6 +693,13 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
|||||||
if self.validation_regex and not re.match(self.validation_regex, value):
|
if self.validation_regex and not re.match(self.validation_regex, value):
|
||||||
raise ValidationError(_("Value must match regex '{regex}'").format(regex=self.validation_regex))
|
raise ValidationError(_("Value must match regex '{regex}'").format(regex=self.validation_regex))
|
||||||
|
|
||||||
|
# Validate URL field
|
||||||
|
elif self.type == CustomFieldTypeChoices.TYPE_URL:
|
||||||
|
if type(value) is not str:
|
||||||
|
raise ValidationError(_("Value must be a string."))
|
||||||
|
if self.validation_regex and not re.match(self.validation_regex, value):
|
||||||
|
raise ValidationError(_("Value must match regex '{regex}'").format(regex=self.validation_regex))
|
||||||
|
|
||||||
# Validate integer
|
# Validate integer
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_INTEGER:
|
elif self.type == CustomFieldTypeChoices.TYPE_INTEGER:
|
||||||
if type(value) is not int:
|
if type(value) is not int:
|
||||||
|
|||||||
@ -1300,6 +1300,28 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
response = self.client.patch(url, data, format='json', **self.header)
|
response = self.client.patch(url, data, format='json', **self.header)
|
||||||
self.assertHttpStatus(response, status.HTTP_200_OK)
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
def test_url_regex_validation(self):
|
||||||
|
"""
|
||||||
|
Test that validation_regex is applied to URL custom fields (fixes #20498).
|
||||||
|
"""
|
||||||
|
site2 = Site.objects.get(name='Site 2')
|
||||||
|
url = reverse('dcim-api:site-detail', kwargs={'pk': site2.pk})
|
||||||
|
self.add_permissions('dcim.change_site')
|
||||||
|
|
||||||
|
cf_url = CustomField.objects.get(name='url_field')
|
||||||
|
cf_url.validation_regex = r'^https://' # Require HTTPS
|
||||||
|
cf_url.save()
|
||||||
|
|
||||||
|
# Test invalid URL (http instead of https)
|
||||||
|
data = {'custom_fields': {'url_field': 'http://example.com'}}
|
||||||
|
response = self.client.patch(url, data, format='json', **self.header)
|
||||||
|
self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# Test valid URL (https)
|
||||||
|
data = {'custom_fields': {'url_field': 'https://example.com'}}
|
||||||
|
response = self.client.patch(url, data, format='json', **self.header)
|
||||||
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
|
||||||
def test_uniqueness_validation(self):
|
def test_uniqueness_validation(self):
|
||||||
# Create a unique custom field
|
# Create a unique custom field
|
||||||
cf_text = CustomField.objects.get(name='text_field')
|
cf_text = CustomField.objects.get(name='text_field')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user