mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-20 20:32:25 -06:00
Merge branch 'develop' into virtualization
This commit is contained in:
@@ -85,7 +85,13 @@ class ValidatedModelSerializer(ModelSerializer):
|
||||
"""
|
||||
Extends the built-in ModelSerializer to enforce calling clean() on the associated model during validation.
|
||||
"""
|
||||
def validate(self, attrs):
|
||||
def validate(self, data):
|
||||
|
||||
# Remove custom field data (if any) prior to model validation
|
||||
attrs = data.copy()
|
||||
attrs.pop('custom_fields', None)
|
||||
|
||||
# Run clean() on an instance of the model
|
||||
if self.instance is None:
|
||||
instance = self.Meta.model(**attrs)
|
||||
else:
|
||||
@@ -93,7 +99,8 @@ class ValidatedModelSerializer(ModelSerializer):
|
||||
for k, v in attrs.items():
|
||||
setattr(instance, k, v)
|
||||
instance.clean()
|
||||
return attrs
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class ChoiceFieldSerializer(Field):
|
||||
|
||||
@@ -7,9 +7,10 @@ from mptt.forms import TreeNodeMultipleChoiceField
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.validators import URLValidator
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from .validators import EnhancedURLValidator
|
||||
|
||||
|
||||
COLOR_CHOICES = (
|
||||
('aa1409', 'Dark red'),
|
||||
@@ -444,17 +445,11 @@ class FilterTreeNodeMultipleChoiceField(FilterChoiceFieldMixin, TreeNodeMultiple
|
||||
|
||||
class LaxURLField(forms.URLField):
|
||||
"""
|
||||
Custom URLField which allows any valid URL scheme
|
||||
Modifies Django's built-in URLField in two ways:
|
||||
1) Allow any valid scheme per RFC 3986 section 3.1
|
||||
2) Remove the requirement for fully-qualified domain names (e.g. http://myserver/ is valid)
|
||||
"""
|
||||
|
||||
class AnyURLScheme(object):
|
||||
# A fake URL list which "contains" all scheme names abiding by the syntax defined in RFC 3986 section 3.1
|
||||
def __contains__(self, item):
|
||||
if not item or not re.match('^[a-z][0-9a-z+\-.]*$', item.lower()):
|
||||
return False
|
||||
return True
|
||||
|
||||
default_validators = [URLValidator(schemes=AnyURLScheme())]
|
||||
default_validators = [EnhancedURLValidator()]
|
||||
|
||||
|
||||
#
|
||||
|
||||
@@ -14,7 +14,7 @@ class BaseTable(tables.Table):
|
||||
|
||||
# Set default empty_text if none was provided
|
||||
if self.empty_text is None:
|
||||
self.empty_text = 'No {} found.'.format(self._meta.model._meta.verbose_name_plural)
|
||||
self.empty_text = 'No {} found'.format(self._meta.model._meta.verbose_name_plural)
|
||||
|
||||
class Meta:
|
||||
attrs = {
|
||||
|
||||
@@ -78,6 +78,27 @@ def bettertitle(value):
|
||||
return ' '.join([w[0].upper() + w[1:] for w in value.split()])
|
||||
|
||||
|
||||
@register.filter()
|
||||
def humanize_speed(speed):
|
||||
"""
|
||||
Humanize speeds given in Kbps. Examples:
|
||||
|
||||
1544 => "1.544 Mbps"
|
||||
100000 => "100 Mbps"
|
||||
10000000 => "10 Gbps"
|
||||
"""
|
||||
if speed >= 1000000000 and speed % 1000000000 == 0:
|
||||
return '{} Tbps'.format(int(speed / 1000000000))
|
||||
elif speed >= 1000000 and speed % 1000000 == 0:
|
||||
return '{} Gbps'.format(int(speed / 1000000))
|
||||
elif speed >= 1000 and speed % 1000 == 0:
|
||||
return '{} Mbps'.format(int(speed / 1000))
|
||||
elif speed >= 1000:
|
||||
return '{} Mbps'.format(float(speed) / 1000)
|
||||
else:
|
||||
return '{} Kbps'.format(speed)
|
||||
|
||||
|
||||
@register.filter()
|
||||
def example_choices(field, arg=3):
|
||||
"""
|
||||
|
||||
30
netbox/utilities/validators.py
Normal file
30
netbox/utilities/validators.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from django.core.validators import _lazy_re_compile, URLValidator
|
||||
|
||||
|
||||
class EnhancedURLValidator(URLValidator):
|
||||
"""
|
||||
Extends Django's built-in URLValidator to permit the use of hostnames with no domain extension.
|
||||
"""
|
||||
|
||||
class AnyURLScheme(object):
|
||||
"""
|
||||
A fake URL list which "contains" all scheme names abiding by the syntax defined in RFC 3986 section 3.1
|
||||
"""
|
||||
def __contains__(self, item):
|
||||
if not item or not re.match('^[a-z][0-9a-z+\-.]*$', item.lower()):
|
||||
return False
|
||||
return True
|
||||
|
||||
fqdn_re = URLValidator.hostname_re + URLValidator.domain_re + URLValidator.tld_re
|
||||
host_res = [URLValidator.ipv4_re, URLValidator.ipv6_re, fqdn_re, URLValidator.hostname_re]
|
||||
regex = _lazy_re_compile(
|
||||
r'^(?:[a-z0-9\.\-\+]*)://' # Scheme (previously enforced by AnyURLScheme or schemes kwarg)
|
||||
r'(?:\S+(?::\S*)?@)?' # HTTP basic authentication
|
||||
r'(?:' + '|'.join(host_res) + ')' # IPv4, IPv6, FQDN, or hostname
|
||||
r'(?::\d{2,5})?' # Port number
|
||||
r'(?:[/?#][^\s]*)?' # Path
|
||||
r'\Z', re.IGNORECASE)
|
||||
schemes = AnyURLScheme()
|
||||
Reference in New Issue
Block a user