Misc cleanup

This commit is contained in:
Jeremy Stretch 2023-07-27 09:28:31 -04:00
parent 9f93c028f1
commit d8da99f225
9 changed files with 31 additions and 23 deletions

View File

@ -1,6 +1,8 @@
# Custom Field Choice Sets
Single- and multi-selection [custom fields documentation](../../customization/custom-fields.md) must define a set of valid choices from which the user may choose when defining the field value. These choices are defined as sets that may be reused among multiple custom fields.
Single- and multi-selection [custom fields](../../customization/custom-fields.md) must define a set of valid choices from which the user may choose when defining the field value. These choices are defined as sets that may be reused among multiple custom fields.
A choice set must define a base choice set and/or a set of arbitrary extra choices.
## Fields
@ -12,12 +14,13 @@ The human-friendly name of the choice set.
The set of pre-defined choices to include. Available sets are listed below. This is an optional setting.
* IATA airport codes
* ISO 3166 - Two-letter country codes
* UN/LOCODE - Five-character location identifiers
### Extra Choices
A list of additional choices, one per line.
A set of custom choices that will be appended to the base choice set (if any).
### Order Alphabetically

View File

@ -78,13 +78,10 @@ class CustomFieldChoiceSetViewSet(NetBoxModelViewSet):
q = q.lower()
choices = [c for c in choices if q in c[0].lower() or q in c[1].lower()]
page = self.paginate_queryset(choices)
if page is not None:
# Paginate data
if page := self.paginate_queryset(choices):
data = [
{
'value': c[0],
'label': c[1],
} for c in page
{'value': c[0], 'label': c[1]} for c in page
]
return self.get_paginated_response(data)

View File

@ -73,9 +73,9 @@ class CustomFieldChoiceSetBaseChoices(ChoiceSet):
UN_LOCODE = 'UN_LOCODE'
CHOICES = (
(IATA, 'IATA'),
(ISO_3166, 'ISO 3166'),
(UN_LOCODE, 'UN/LOCODE'),
(IATA, 'IATA (Airport codes)'),
(ISO_3166, 'ISO 3166 (Country codes)'),
(UN_LOCODE, 'UN/LOCODE (Location codes)'),
)

View File

@ -66,7 +66,7 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
base_choices = CSVChoiceField(
choices=CustomFieldChoiceSetBaseChoices,
required=False,
help_text=_('The classification of entry')
help_text=_('The base set of predefined choices to use (if any)')
)
class Meta:

View File

@ -19,7 +19,6 @@ from utilities.forms.fields import (
CommentField, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DynamicModelChoiceField,
DynamicModelMultipleChoiceField, JSONField, SlugField,
)
from utilities.forms.widgets import ChoicesWidget
from virtualization.models import Cluster, ClusterGroup, ClusterType

View File

@ -410,7 +410,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
# Select
elif self.type in (CustomFieldTypeChoices.TYPE_SELECT, CustomFieldTypeChoices.TYPE_MULTISELECT):
choices = self.choices
choices = self.choice_set.choices
default_choice = self.default if self.default in self.choices else None
if not required or default_choice is None:
@ -427,7 +427,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
field_class = CSVMultipleChoiceField if for_csv_import else DynamicMultipleChoiceField
widget_class = APISelectMultiple
field = field_class(
choices=self.choice_set.choices,
choices=choices,
required=required,
initial=initial,
widget=widget_class(api_url=f'/api/extras/custom-field-choices/{self.choice_set.pk}/choices/')
@ -664,7 +664,7 @@ class CustomFieldChoiceSet(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel
)
order_alphabetically = models.BooleanField(
default=False,
help_text=_('Choices are automatically ordered alphabetically on save')
help_text=_('Choices are automatically ordered alphabetically')
)
clone_fields = ('extra_choices', 'order_alphabetically')

View File

@ -64,11 +64,9 @@ class CustomFieldTable(NetBoxTable):
)
content_types = columns.ContentTypesColumn()
required = columns.BooleanColumn()
ui_visibility = columns.ChoiceFieldColumn(
verbose_name="UI visibility"
)
ui_visibility = columns.ChoiceFieldColumn(verbose_name="UI visibility")
description = columns.MarkdownColumn()
choices = columns.ChoiceSetColumn(
choices = columns.ChoicesColumn(
max_items=10,
orderable=False
)
@ -92,7 +90,7 @@ class CustomFieldChoiceSetTable(NetBoxTable):
extra_choices = tables.TemplateColumn(
template_code="""{% for k, v in value.items %}{{ v }}{% if not forloop.last %}, {% endif %}{% endfor %}"""
)
choices = columns.ChoiceSetColumn(
choices = columns.ChoicesColumn(
max_items=10,
orderable=False
)

View File

@ -24,7 +24,7 @@ __all__ = (
'ArrayColumn',
'BooleanColumn',
'ChoiceFieldColumn',
'ChoiceSetColumn',
'ChoicesColumn',
'ColorColumn',
'ColoredLabelColumn',
'ContentTypeColumn',
@ -623,7 +623,7 @@ class ArrayColumn(tables.Column):
return ', '.join(value)
class ChoiceSetColumn(tables.Column):
class ChoicesColumn(tables.Column):
"""
Display the human-friendly labels of a set of choices.
"""

View File

@ -1,6 +1,7 @@
from django import forms
__all__ = (
'ArrayWidget',
'ChoicesWidget',
'ClearableFileInput',
'MarkdownWidget',
@ -46,6 +47,16 @@ class SlugWidget(forms.TextInput):
template_name = 'widgets/sluginput.html'
class ArrayWidget(forms.Textarea):
"""
Render each item of an array on a new line within a textarea for easy editing/
"""
def format_value(self, value):
if value is None or not len(value):
return None
return '\n'.join(value)
class ChoicesWidget(forms.Textarea):
"""
Render each key-value pair of a dictionary on a new line within a textarea for easy editing.