From c9c537a1b9b4cadb9c29579f984e1f96c2583792 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 1 Oct 2021 20:22:54 -0400 Subject: [PATCH] Fixes #6817: Custom field columns should be removed from tables upon their deletion --- docs/release-notes/version-3.0.md | 1 + netbox/utilities/tables.py | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index 9a5862f6c..7bba5c4db 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -12,6 +12,7 @@ ### Bug Fixes * [#6433](https://github.com/netbox-community/netbox/issues/6433) - Fix bulk editing of child prefixes under aggregate view +* [#6817](https://github.com/netbox-community/netbox/issues/6817) - Custom field columns should be removed from tables upon their deletion * [#6895](https://github.com/netbox-community/netbox/issues/6895) - Remove errant markup for null values in CSV export * [#7373](https://github.com/netbox-community/netbox/issues/7373) - Fix flashing when server, client, and browser color-mode preferences are mismatched * [#7397](https://github.com/netbox-community/netbox/issues/7397) - Fix AttributeError exception when rendering export template for devices via REST API diff --git a/netbox/utilities/tables.py b/netbox/utilities/tables.py index 09fb8350c..c8d0a0e43 100644 --- a/netbox/utilities/tables.py +++ b/netbox/utilities/tables.py @@ -29,13 +29,18 @@ class BaseTable(tables.Table): 'class': 'table table-hover object-list', } - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, user=None, extra_columns=None, **kwargs): # Add custom field columns obj_type = ContentType.objects.get_for_model(self._meta.model) - for cf in CustomField.objects.filter(content_types=obj_type): - self.base_columns[f'cf_{cf.name}'] = CustomFieldColumn(cf) + cf_columns = [ + (f'cf_{cf.name}', CustomFieldColumn(cf)) for cf in CustomField.objects.filter(content_types=obj_type) + ] + if extra_columns is not None: + extra_columns.extend(cf_columns) + else: + extra_columns = cf_columns - super().__init__(*args, **kwargs) + super().__init__(*args, extra_columns=extra_columns, **kwargs) # Set default empty_text if none was provided if self.empty_text is None: @@ -50,17 +55,22 @@ class BaseTable(tables.Table): # Apply custom column ordering for user if user is not None and not isinstance(user, AnonymousUser): - columns = user.config.get(f"tables.{self.__class__.__name__}.columns") - if columns: + selected_columns = user.config.get(f"tables.{self.__class__.__name__}.columns") + if selected_columns: pk = self.base_columns.pop('pk', None) actions = self.base_columns.pop('actions', None) - for name, column in self.base_columns.items(): - if name in columns: + for name, column in self.columns.items(): + if name in selected_columns: self.columns.show(name) else: self.columns.hide(name) - self.sequence = [c for c in columns if c in self.base_columns] + # Rearrange the sequence to list selected columns first, followed by all remaining columns + # TODO: There's probably a more clever way to accomplish this + self.sequence = [ + *[c for c in selected_columns if c in self.columns.names()], + *[c for c in self.columns.names() if c not in selected_columns] + ] # Always include PK and actions column, if defined on the table if pk: