mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fixes #10461: Enable filtering by read-only custom fields in the UI
This commit is contained in:
@ -8,6 +8,7 @@
|
|||||||
* [#10435](https://github.com/netbox-community/netbox/issues/10435) - Fix exception when filtering VLANs by virtual machine with no cluster assigned
|
* [#10435](https://github.com/netbox-community/netbox/issues/10435) - Fix exception when filtering VLANs by virtual machine with no cluster assigned
|
||||||
* [#10439](https://github.com/netbox-community/netbox/issues/10439) - Fix form widget styling for DeviceType airflow field
|
* [#10439](https://github.com/netbox-community/netbox/issues/10439) - Fix form widget styling for DeviceType airflow field
|
||||||
* [#10445](https://github.com/netbox-community/netbox/issues/10445) - Avoid rounding virtual machine memory values
|
* [#10445](https://github.com/netbox-community/netbox/issues/10445) - Avoid rounding virtual machine memory values
|
||||||
|
* [#10461](https://github.com/netbox-community/netbox/issues/10461) - Enable filtering by read-only custom fields in the UI
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -34,7 +34,9 @@ class CustomFieldsMixin:
|
|||||||
return ContentType.objects.get_for_model(self.model)
|
return ContentType.objects.get_for_model(self.model)
|
||||||
|
|
||||||
def _get_custom_fields(self, content_type):
|
def _get_custom_fields(self, content_type):
|
||||||
return CustomField.objects.filter(content_types=content_type)
|
return CustomField.objects.filter(content_types=content_type).exclude(
|
||||||
|
ui_visibility=CustomFieldVisibilityChoices.VISIBILITY_HIDDEN
|
||||||
|
)
|
||||||
|
|
||||||
def _get_form_field(self, customfield):
|
def _get_form_field(self, customfield):
|
||||||
return customfield.to_form_field()
|
return customfield.to_form_field()
|
||||||
@ -50,13 +52,6 @@ class CustomFieldsMixin:
|
|||||||
field_name = f'cf_{customfield.name}'
|
field_name = f'cf_{customfield.name}'
|
||||||
self.fields[field_name] = self._get_form_field(customfield)
|
self.fields[field_name] = self._get_form_field(customfield)
|
||||||
|
|
||||||
if customfield.ui_visibility == CustomFieldVisibilityChoices.VISIBILITY_READ_ONLY:
|
|
||||||
self.fields[field_name].disabled = True
|
|
||||||
if self.fields[field_name].help_text:
|
|
||||||
self.fields[field_name].help_text += '<br />'
|
|
||||||
self.fields[field_name].help_text += '<i class="mdi mdi-alert-circle-outline"></i> ' \
|
|
||||||
'Field is set to read-only.'
|
|
||||||
|
|
||||||
# Annotate the field in the list of CustomField form fields
|
# Annotate the field in the list of CustomField form fields
|
||||||
self.custom_fields[field_name] = customfield
|
self.custom_fields[field_name] = customfield
|
||||||
if customfield.group_name not in self.custom_field_groups:
|
if customfield.group_name not in self.custom_field_groups:
|
||||||
|
@ -297,12 +297,13 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
|||||||
return model.objects.filter(pk__in=value)
|
return model.objects.filter(pk__in=value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def to_form_field(self, set_initial=True, enforce_required=True, for_csv_import=False):
|
def to_form_field(self, set_initial=True, enforce_required=True, enforce_visibility=True, for_csv_import=False):
|
||||||
"""
|
"""
|
||||||
Return a form field suitable for setting a CustomField's value for an object.
|
Return a form field suitable for setting a CustomField's value for an object.
|
||||||
|
|
||||||
set_initial: Set initial data for the field. This should be False when generating a field for bulk editing.
|
set_initial: Set initial data for the field. This should be False when generating a field for bulk editing.
|
||||||
enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing.
|
enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing.
|
||||||
|
enforce_visibility: Honor the value of CustomField.ui_visibility. Set to False for filtering.
|
||||||
for_csv_import: Return a form field suitable for bulk import of objects in CSV format.
|
for_csv_import: Return a form field suitable for bulk import of objects in CSV format.
|
||||||
"""
|
"""
|
||||||
initial = self.default if set_initial else None
|
initial = self.default if set_initial else None
|
||||||
@ -398,6 +399,12 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
|||||||
if self.description:
|
if self.description:
|
||||||
field.help_text = escape(self.description)
|
field.help_text = escape(self.description)
|
||||||
|
|
||||||
|
# Annotate read-only fields
|
||||||
|
if enforce_visibility and self.ui_visibility == CustomFieldVisibilityChoices.VISIBILITY_READ_ONLY:
|
||||||
|
field.disabled = True
|
||||||
|
prepend = '<br />' if field.help_text else ''
|
||||||
|
field.help_text += f'{prepend}<i class="mdi mdi-alert-circle-outline"></i> Field is set to read-only.'
|
||||||
|
|
||||||
return field
|
return field
|
||||||
|
|
||||||
def to_filter(self, lookup_expr=None):
|
def to_filter(self, lookup_expr=None):
|
||||||
|
@ -2,7 +2,7 @@ from django import forms
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices
|
from extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices, CustomFieldVisibilityChoices
|
||||||
from extras.forms.customfields import CustomFieldsMixin
|
from extras.forms.customfields import CustomFieldsMixin
|
||||||
from extras.models import CustomField, Tag
|
from extras.models import CustomField, Tag
|
||||||
from utilities.forms import BootstrapMixin, CSVModelForm
|
from utilities.forms import BootstrapMixin, CSVModelForm
|
||||||
@ -125,10 +125,10 @@ class NetBoxModelFilterSetForm(BootstrapMixin, CustomFieldsMixin, forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _get_custom_fields(self, content_type):
|
def _get_custom_fields(self, content_type):
|
||||||
return CustomField.objects.filter(content_types=content_type).exclude(
|
return super()._get_custom_fields(content_type).exclude(
|
||||||
Q(filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED) |
|
Q(filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED) |
|
||||||
Q(type=CustomFieldTypeChoices.TYPE_JSON)
|
Q(type=CustomFieldTypeChoices.TYPE_JSON)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_form_field(self, customfield):
|
def _get_form_field(self, customfield):
|
||||||
return customfield.to_form_field(set_initial=False, enforce_required=False)
|
return customfield.to_form_field(set_initial=False, enforce_required=False, enforce_visibility=False)
|
||||||
|
Reference in New Issue
Block a user