mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-12 11:29:36 -06:00
Address PR feedback: Move FORM_FIELD_LOOKUPS to module-level constant
Extracts the field type to lookup mappings from FilterModifierMixin class attribute to a module-level constant for better reusability.
This commit is contained in:
parent
05e1317f5e
commit
ac74d9f9be
@ -13,82 +13,10 @@ __all__ = (
|
||||
'CheckLastUpdatedMixin',
|
||||
'DistanceValidationMixin',
|
||||
'FilterModifierMixin',
|
||||
'FORM_FIELD_LOOKUPS',
|
||||
)
|
||||
|
||||
|
||||
class BackgroundJobMixin(forms.Form):
|
||||
background_job = forms.BooleanField(
|
||||
label=_('Background job'),
|
||||
help_text=_("Execute this task via a background job"),
|
||||
required=False,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Declare background_job a meta field
|
||||
if hasattr(self, 'meta_fields'):
|
||||
self.meta_fields.append('background_job')
|
||||
else:
|
||||
self.meta_fields = ['background_job']
|
||||
|
||||
|
||||
class CheckLastUpdatedMixin(forms.Form):
|
||||
"""
|
||||
Checks whether the object being saved has been updated since the form was initialized. If so, validation fails.
|
||||
This prevents a user from inadvertently overwriting any changes made to the object between when the form was
|
||||
initialized and when it was submitted.
|
||||
|
||||
This validation does not apply to newly created objects, or if the `_init_time` field is not present in the form
|
||||
data.
|
||||
"""
|
||||
_init_time = forms.DecimalField(
|
||||
initial=time.time,
|
||||
required=False,
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# Skip for absent or newly created instances
|
||||
if not self.instance or not self.instance.pk:
|
||||
return
|
||||
|
||||
# Skip if a form init time has not been specified
|
||||
if not (form_init_time := self.cleaned_data.get('_init_time')):
|
||||
return
|
||||
|
||||
# Skip if the object does not have a last_updated value
|
||||
if not (last_updated := getattr(self.instance, 'last_updated', None)):
|
||||
return
|
||||
|
||||
# Check that the submitted initialization time is not earlier than the object's modification time
|
||||
if form_init_time < last_updated.timestamp():
|
||||
raise forms.ValidationError(_(
|
||||
"This object has been modified since the form was rendered. Please consult the object's change "
|
||||
"log for details."
|
||||
))
|
||||
|
||||
|
||||
class DistanceValidationMixin(forms.Form):
|
||||
distance = forms.DecimalField(
|
||||
required=False,
|
||||
validators=[
|
||||
MinValueValidator(Decimal(0)),
|
||||
MaxValueValidator(Decimal(100000)),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class FilterModifierMixin:
|
||||
"""
|
||||
Mixin that enhances filter form fields with lookup modifier dropdowns.
|
||||
|
||||
Automatically detects fields that could benefit from multiple lookup options
|
||||
and wraps their widgets with FilterModifierWidget.
|
||||
"""
|
||||
|
||||
# Mapping of form field types to their supported lookups
|
||||
FORM_FIELD_LOOKUPS = {
|
||||
forms.CharField: [
|
||||
@ -165,6 +93,80 @@ class FilterModifierMixin:
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class BackgroundJobMixin(forms.Form):
|
||||
background_job = forms.BooleanField(
|
||||
label=_('Background job'),
|
||||
help_text=_("Execute this task via a background job"),
|
||||
required=False,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Declare background_job a meta field
|
||||
if hasattr(self, 'meta_fields'):
|
||||
self.meta_fields.append('background_job')
|
||||
else:
|
||||
self.meta_fields = ['background_job']
|
||||
|
||||
|
||||
class CheckLastUpdatedMixin(forms.Form):
|
||||
"""
|
||||
Checks whether the object being saved has been updated since the form was initialized. If so, validation fails.
|
||||
This prevents a user from inadvertently overwriting any changes made to the object between when the form was
|
||||
initialized and when it was submitted.
|
||||
|
||||
This validation does not apply to newly created objects, or if the `_init_time` field is not present in the form
|
||||
data.
|
||||
"""
|
||||
_init_time = forms.DecimalField(
|
||||
initial=time.time,
|
||||
required=False,
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# Skip for absent or newly created instances
|
||||
if not self.instance or not self.instance.pk:
|
||||
return
|
||||
|
||||
# Skip if a form init time has not been specified
|
||||
if not (form_init_time := self.cleaned_data.get('_init_time')):
|
||||
return
|
||||
|
||||
# Skip if the object does not have a last_updated value
|
||||
if not (last_updated := getattr(self.instance, 'last_updated', None)):
|
||||
return
|
||||
|
||||
# Check that the submitted initialization time is not earlier than the object's modification time
|
||||
if form_init_time < last_updated.timestamp():
|
||||
raise forms.ValidationError(_(
|
||||
"This object has been modified since the form was rendered. Please consult the object's change "
|
||||
"log for details."
|
||||
))
|
||||
|
||||
|
||||
class DistanceValidationMixin(forms.Form):
|
||||
distance = forms.DecimalField(
|
||||
required=False,
|
||||
validators=[
|
||||
MinValueValidator(Decimal(0)),
|
||||
MaxValueValidator(Decimal(100000)),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class FilterModifierMixin:
|
||||
"""
|
||||
Mixin that enhances filter form fields with lookup modifier dropdowns.
|
||||
|
||||
Automatically detects fields that could benefit from multiple lookup options
|
||||
and wraps their widgets with FilterModifierWidget.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._enhance_fields_with_modifiers()
|
||||
@ -217,8 +219,8 @@ class FilterModifierMixin:
|
||||
"""Determine the available lookup choices for a given field."""
|
||||
# Walk up the MRO to find a known field type
|
||||
for field_class in field.__class__.__mro__:
|
||||
if field_class in self.FORM_FIELD_LOOKUPS:
|
||||
return self.FORM_FIELD_LOOKUPS[field_class]
|
||||
if field_class in FORM_FIELD_LOOKUPS:
|
||||
return FORM_FIELD_LOOKUPS[field_class]
|
||||
|
||||
# Unknown field type - return single exact option (no enhancement)
|
||||
return [('exact', _('Is'))]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user