Closes #21209: Accept case-insensitive model names in configuration (#21275)

NetBox now accepts case-insensitive model identifiers in configuration, allowing
both lowercase (e.g. "dcim.site") and PascalCase (e.g. "dcim.Site") for
DEFAULT_DASHBOARD, CUSTOM_VALIDATORS, and PROTECTION_RULES.
This makes model name handling consistent with FIELD_CHOICES.

- Add a shared case-insensitive config lookup helper (get_config_value_ci())
- Use the helper in extras/signals.py and core/signals.py
- Update FIELD_CHOICES ChoiceSetMeta to support case-insensitive replace/extend
  (only compute extend choices if no replacement is defined)
- Add unit tests for get_config_value_ci()
- Add integration tests for case-insensitive FIELD_CHOICES replacement/extension
- Update documentation examples to use PascalCase consistently
This commit is contained in:
Aditya Sharma
2026-01-30 18:18:38 +05:30
committed by GitHub
parent c98f55dbd2
commit bec5ecf6a9
8 changed files with 91 additions and 14 deletions

View File

@@ -75,10 +75,11 @@ def get_bookmarks_object_type_choices():
def get_models_from_content_types(content_types):
"""
Return a list of models corresponding to the given content types, identified by natural key.
Accepts both lowercase (e.g. "dcim.site") and PascalCase (e.g. "dcim.Site") model names.
"""
models = []
for content_type_id in content_types:
app_label, model_name = content_type_id.split('.')
app_label, model_name = content_type_id.lower().split('.')
try:
content_type = ObjectType.objects.get_by_natural_key(app_label, model_name)
if content_type.model_class():

View File

@@ -9,6 +9,7 @@ from extras.models import EventRule, Notification, Subscription
from netbox.config import get_config
from netbox.models.features import has_feature
from netbox.signals import post_clean
from utilities.data import get_config_value_ci
from utilities.exceptions import AbortRequest
from .models import CustomField, TaggedItem
from .utils import run_validators
@@ -65,7 +66,7 @@ def run_save_validators(sender, instance, **kwargs):
Run any custom validation rules for the model prior to calling save().
"""
model_name = f'{sender._meta.app_label}.{sender._meta.model_name}'
validators = get_config().CUSTOM_VALIDATORS.get(model_name, [])
validators = get_config_value_ci(get_config().CUSTOM_VALIDATORS, model_name, default=[])
run_validators(instance, validators)