1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #8358: Fix inconsistent styling of custom fields on filter & bulk edit forms

This commit is contained in:
jeremystretch
2022-01-14 14:23:58 -05:00
parent b0948ea018
commit 2b31154834
4 changed files with 41 additions and 43 deletions

View File

@ -24,6 +24,7 @@
* [#8319](https://github.com/netbox-community/netbox/issues/8319) - Custom URL fields should honor `ALLOWED_URL_SCHEMES` config parameter * [#8319](https://github.com/netbox-community/netbox/issues/8319) - Custom URL fields should honor `ALLOWED_URL_SCHEMES` config parameter
* [#8342](https://github.com/netbox-community/netbox/issues/8342) - Restore `created` & `last_updated` fields missing from several REST API serializers * [#8342](https://github.com/netbox-community/netbox/issues/8342) - Restore `created` & `last_updated` fields missing from several REST API serializers
* [#8357](https://github.com/netbox-community/netbox/issues/8357) - Add missing tags field to location filter form * [#8357](https://github.com/netbox-community/netbox/issues/8357) - Add missing tags field to location filter form
* [#8358](https://github.com/netbox-community/netbox/issues/8358) - Fix inconsistent styling of custom fields on filter & bulk edit forms
--- ---

View File

@ -4,7 +4,7 @@ from django.db.models import Q
from extras.choices import * from extras.choices import *
from extras.models import * from extras.models import *
from utilities.forms import BootstrapMixin, BulkEditForm, CSVModelForm, FilterForm from utilities.forms import BootstrapMixin, BulkEditBaseForm, CSVModelForm
__all__ = ( __all__ = (
'CustomFieldModelCSVForm', 'CustomFieldModelCSVForm',
@ -34,6 +34,9 @@ class CustomFieldsMixin:
raise NotImplementedError(f"{self.__class__.__name__} must specify a model class.") raise NotImplementedError(f"{self.__class__.__name__} must specify a model class.")
return ContentType.objects.get_for_model(self.model) return ContentType.objects.get_for_model(self.model)
def _get_custom_fields(self, content_type):
return CustomField.objects.filter(content_types=content_type)
def _get_form_field(self, customfield): def _get_form_field(self, customfield):
return customfield.to_form_field() return customfield.to_form_field()
@ -41,10 +44,7 @@ class CustomFieldsMixin:
""" """
Append form fields for all CustomFields assigned to this object type. Append form fields for all CustomFields assigned to this object type.
""" """
content_type = self._get_content_type() for customfield in self._get_custom_fields(self._get_content_type()):
# Append form fields; assign initial values if modifying and existing object
for customfield in CustomField.objects.filter(content_types=content_type):
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)
@ -86,40 +86,37 @@ class CustomFieldModelCSVForm(CSVModelForm, CustomFieldModelForm):
return customfield.to_form_field(for_csv_import=True) return customfield.to_form_field(for_csv_import=True)
class CustomFieldModelBulkEditForm(BulkEditForm): class CustomFieldModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, BulkEditBaseForm):
def __init__(self, *args, **kwargs): def _get_form_field(self, customfield):
super().__init__(*args, **kwargs) return customfield.to_form_field(set_initial=False, enforce_required=False)
self.custom_fields = [] def _append_customfield_fields(self):
self.obj_type = ContentType.objects.get_for_model(self.model) """
Append form fields for all CustomFields assigned to this object type.
# Add all applicable CustomFields to the form """
custom_fields = CustomField.objects.filter(content_types=self.obj_type) for customfield in self._get_custom_fields(self._get_content_type()):
for cf in custom_fields:
# Annotate non-required custom fields as nullable # Annotate non-required custom fields as nullable
if not cf.required: if not customfield.required:
self.nullable_fields.append(cf.name) self.nullable_fields.append(customfield.name)
self.fields[cf.name] = cf.to_form_field(set_initial=False, enforce_required=False)
# Annotate this as a custom field self.fields[customfield.name] = self._get_form_field(customfield)
self.custom_fields.append(cf.name)
# Annotate the field in the list of CustomField form fields
self.custom_fields.append(customfield.name)
class CustomFieldModelFilterForm(FilterForm): class CustomFieldModelFilterForm(BootstrapMixin, CustomFieldsMixin, forms.Form):
q = forms.CharField(
required=False,
label='Search'
)
def __init__(self, *args, **kwargs): def _get_custom_fields(self, content_type):
return CustomField.objects.filter(content_types=content_type).exclude(
self.obj_type = ContentType.objects.get_for_model(self.model)
super().__init__(*args, **kwargs)
# Add all applicable CustomFields to the form
self.custom_field_filters = []
custom_fields = CustomField.objects.filter(content_types=self.obj_type).exclude(
Q(filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED) | Q(filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED) |
Q(type=CustomFieldTypeChoices.TYPE_JSON) Q(type=CustomFieldTypeChoices.TYPE_JSON)
) )
for cf in custom_fields:
field_name = f'cf_{cf.name}' def _get_form_field(self, customfield):
self.fields[field_name] = cf.to_form_field(set_initial=False, enforce_required=False) return customfield.to_form_field(set_initial=False, enforce_required=False)
self.custom_field_filters.append(field_name)

View File

@ -24,17 +24,17 @@
{% else %} {% else %}
{# List all non-customfield filters as declared in the form class #} {# List all non-customfield filters as declared in the form class #}
{% for field in filter_form.visible_fields %} {% for field in filter_form.visible_fields %}
{% if not filter_form.custom_field_filters or field.name not in filter_form.custom_field_filters %} {% if not filter_form.custom_fields or field.name not in filter_form.custom_fields %}
<div class="col col-12"> <div class="col col-12">
{% render_field field %} {% render_field field %}
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if filter_form.custom_field_filters %} {% if filter_form.custom_fields %}
{# List all custom field filters #} {# List all custom field filters #}
<hr class="card-divider mt-0" /> <hr class="card-divider mt-0" />
{% for name in filter_form.custom_field_filters %} {% for name in filter_form.custom_fields %}
<div class="col col-12"> <div class="col col-12">
{% with field=filter_form|get_item:name %} {% with field=filter_form|get_item:name %}
{% render_field field %} {% render_field field %}

View File

@ -3,7 +3,6 @@ import re
import yaml import yaml
from django import forms from django import forms
from django.utils.translation import gettext as _
from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSelect from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSelect
@ -11,6 +10,7 @@ from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSel
__all__ = ( __all__ = (
'BootstrapMixin', 'BootstrapMixin',
'BulkEditForm', 'BulkEditForm',
'BulkEditBaseForm',
'BulkRenameForm', 'BulkRenameForm',
'ConfirmationForm', 'ConfirmationForm',
'CSVModelForm', 'CSVModelForm',
@ -75,11 +75,10 @@ class ConfirmationForm(BootstrapMixin, ReturnURLForm):
confirm = forms.BooleanField(required=True, widget=forms.HiddenInput(), initial=True) confirm = forms.BooleanField(required=True, widget=forms.HiddenInput(), initial=True)
class BulkEditForm(BootstrapMixin, forms.Form): class BulkEditBaseForm(forms.Form):
""" """
Base form for editing multiple objects in bulk Base form for editing multiple objects in bulk
""" """
def __init__(self, model, *args, **kwargs): def __init__(self, model, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.model = model self.model = model
@ -90,6 +89,10 @@ class BulkEditForm(BootstrapMixin, forms.Form):
self.nullable_fields = self.Meta.nullable_fields self.nullable_fields = self.Meta.nullable_fields
class BulkEditForm(BootstrapMixin, BulkEditBaseForm):
pass
class BulkRenameForm(BootstrapMixin, forms.Form): class BulkRenameForm(BootstrapMixin, forms.Form):
""" """
An extendable form to be used for renaming objects in bulk. An extendable form to be used for renaming objects in bulk.
@ -185,10 +188,7 @@ class FilterForm(BootstrapMixin, forms.Form):
""" """
q = forms.CharField( q = forms.CharField(
required=False, required=False,
widget=forms.TextInput( label='Search'
attrs={'placeholder': _('All fields')}
),
label=_('Search')
) )