diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index e7e8d2b84..011afa42d 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -972,7 +972,7 @@ class CustomFieldChoiceSet(CloningMixin, ExportTemplatesMixin, OwnerMixin, Chang extra_choice_values = set() if self.base_choices: - valid_choice_values.update(CHOICE_SETS.get(self.base_choices).values()) + valid_choice_values.update(value for value, _ in CHOICE_SETS.get(self.base_choices)) if self.extra_choices: for value, _label in self.extra_choices: @@ -1031,7 +1031,7 @@ class CustomFieldChoiceSet(CloningMixin, ExportTemplatesMixin, OwnerMixin, Chang def save(self, *args, **kwargs): # Sort choices if alphabetical ordering is enforced - if self.order_alphabetically: + if self.order_alphabetically and self.extra_choices: self.extra_choices = sorted(self.extra_choices, key=lambda x: x[0]) return super().save(*args, **kwargs) diff --git a/netbox/extras/tests/test_customfields.py b/netbox/extras/tests/test_customfields.py index 8c695d382..c7c633991 100644 --- a/netbox/extras/tests/test_customfields.py +++ b/netbox/extras/tests/test_customfields.py @@ -466,6 +466,15 @@ class CustomFieldTestCase(TestCase): self.assertIn('choice_colors', cm.exception.message_dict) + @tag('regression') + def test_choice_set_with_base_choices_validates_without_error(self): + """Regression test for #22325: base-only choice sets must validate.""" + for base in ('IATA', 'ISO_3166', 'UN_LOCODE'): + with self.subTest(base=base): + choice_set = CustomFieldChoiceSet(name=f'Test {base}', base_choices=base, order_alphabetically=True) + choice_set.full_clean() # must not raise + choice_set.save() # must not raise (extra_choices is None) + def test_remove_selected_choice(self): """ Removing a ChoiceSet choice that is referenced by an object should raise