mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Introduce NaturalOrderingField
This commit is contained in:
parent
b3c2b78e8a
commit
b271fd32bd
@ -1,6 +1,7 @@
|
|||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from utilities.ordering import naturalize
|
||||||
from .forms import ColorSelect
|
from .forms import ColorSelect
|
||||||
|
|
||||||
ColorValidator = RegexValidator(
|
ColorValidator = RegexValidator(
|
||||||
@ -35,3 +36,35 @@ class ColorField(models.CharField):
|
|||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
kwargs['widget'] = ColorSelect
|
kwargs['widget'] = ColorSelect
|
||||||
return super().formfield(**kwargs)
|
return super().formfield(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class NaturalOrderingField(models.CharField):
|
||||||
|
"""
|
||||||
|
A field which stores a naturalized representation of its target field, to be used for ordering its parent model.
|
||||||
|
|
||||||
|
:param target_field: Name of the field of the parent model to be naturalized
|
||||||
|
:param naturalize_function: The function used to generate a naturalized value (optional)
|
||||||
|
"""
|
||||||
|
description = "Stores a representation of its target field suitable for natural ordering"
|
||||||
|
|
||||||
|
def __init__(self, target_field, naturalize_function=naturalize, *args, **kwargs):
|
||||||
|
self.target_field = target_field
|
||||||
|
self.naturalize_function = naturalize_function
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def pre_save(self, model_instance, add):
|
||||||
|
"""
|
||||||
|
Generate a naturalized value from the target field
|
||||||
|
"""
|
||||||
|
value = getattr(model_instance, self.target_field)
|
||||||
|
return self.naturalize_function(value, max_length=self.max_length)
|
||||||
|
|
||||||
|
def deconstruct(self):
|
||||||
|
kwargs = super().deconstruct()[3] # Pass kwargs from CharField
|
||||||
|
kwargs['naturalize_function'] = self.naturalize_function
|
||||||
|
return (
|
||||||
|
self.name,
|
||||||
|
'utilities.fields.NaturalOrderingField',
|
||||||
|
['target_field'],
|
||||||
|
kwargs,
|
||||||
|
)
|
||||||
|
31
netbox/utilities/ordering.py
Normal file
31
netbox/utilities/ordering.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize(value, max_length=None, integer_places=8):
|
||||||
|
"""
|
||||||
|
Take an alphanumeric string and prepend all integers to `integer_places` places to ensure the strings
|
||||||
|
are ordered naturally. For example:
|
||||||
|
|
||||||
|
site9router21
|
||||||
|
site10router4
|
||||||
|
site10router19
|
||||||
|
|
||||||
|
becomes:
|
||||||
|
|
||||||
|
site00000009router00000021
|
||||||
|
site00000010router00000004
|
||||||
|
site00000010router00000019
|
||||||
|
|
||||||
|
:param value: The value to be naturalized
|
||||||
|
:param max_length: The maximum length of the returned string. Characters beyond this length will be stripped.
|
||||||
|
:param integer_places: The number of places to which each integer will be expanded. (Default: 8)
|
||||||
|
"""
|
||||||
|
output = []
|
||||||
|
for segment in re.split(r'(\d+)', value):
|
||||||
|
if segment.isdigit():
|
||||||
|
output.append(segment.rjust(integer_places, '0'))
|
||||||
|
elif segment:
|
||||||
|
output.append(segment)
|
||||||
|
ret = ''.join(output)
|
||||||
|
|
||||||
|
return ret[:max_length] if max_length else ret
|
Loading…
Reference in New Issue
Block a user