Просмотр исходного кода

Fixes #19264: Support table configs on child object list views (#19284)

* Fixes #19264: Support table configs on child object list views

* Clear assigned table config when resetting the configuration
Jeremy Stretch 9 месяцев назад
Родитель
Сommit
a83dfff736

+ 4 - 20
netbox/netbox/views/generic/bulk_views.py

@@ -7,7 +7,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRel
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
 from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
 from django.db import transaction, IntegrityError
 from django.db import transaction, IntegrityError
-from django.db.models import ManyToManyField, ProtectedError, Q, RestrictedError
+from django.db.models import ManyToManyField, ProtectedError, RestrictedError
 from django.db.models.fields.reverse_related import ManyToManyRel
 from django.db.models.fields.reverse_related import ManyToManyRel
 from django.forms import ModelMultipleChoiceField, MultipleHiddenInput
 from django.forms import ModelMultipleChoiceField, MultipleHiddenInput
 from django.http import HttpResponse
 from django.http import HttpResponse
@@ -21,7 +21,7 @@ from mptt.models import MPTTModel
 from core.models import ObjectType
 from core.models import ObjectType
 from core.signals import clear_events
 from core.signals import clear_events
 from extras.choices import CustomFieldUIEditableChoices
 from extras.choices import CustomFieldUIEditableChoices
-from extras.models import CustomField, ExportTemplate, TableConfig
+from extras.models import CustomField, ExportTemplate
 from utilities.error_handlers import handle_protectederror
 from utilities.error_handlers import handle_protectederror
 from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
 from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
 from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
 from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
@@ -29,6 +29,7 @@ from utilities.forms.bulk_import import BulkImportForm
 from utilities.htmx import htmx_partial
 from utilities.htmx import htmx_partial
 from utilities.permissions import get_permission_for_model
 from utilities.permissions import get_permission_for_model
 from utilities.query import reapply_model_ordering
 from utilities.query import reapply_model_ordering
+from utilities.tables import get_table_configs
 from utilities.views import GetReturnURLMixin, get_viewname
 from utilities.views import GetReturnURLMixin, get_viewname
 from .base import BaseMultiObjectView
 from .base import BaseMultiObjectView
 from .mixins import ActionsMixin, TableMixin
 from .mixins import ActionsMixin, TableMixin
@@ -140,15 +141,6 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
         model = self.queryset.model
         model = self.queryset.model
         object_type = ObjectType.objects.get_for_model(model)
         object_type = ObjectType.objects.get_for_model(model)
 
 
-        # If a TableConfig has been specified, apply it & update the user's saved preference
-        if tableconfig_id := request.GET.get('tableconfig_id'):
-            tableconfig = get_object_or_404(TableConfig, pk=tableconfig_id)
-            if request.user.is_authenticated:
-                table = self.table.__name__
-                request.user.config.set(f'tables.{table}.columns', tableconfig.columns)
-                request.user.config.set(f'tables.{table}.ordering', tableconfig.ordering, commit=True)
-            return redirect(request.path)
-
         if self.filterset:
         if self.filterset:
             self.queryset = self.filterset(request.GET, self.queryset, request=request).qs
             self.queryset = self.filterset(request.GET, self.queryset, request=request).qs
 
 
@@ -184,14 +176,6 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
         # Render the objects table
         # Render the objects table
         table = self.get_table(self.queryset, request, has_bulk_actions)
         table = self.get_table(self.queryset, request, has_bulk_actions)
 
 
-        # Retrieve available configurations for the table
-        table_configs = TableConfig.objects.filter(
-            Q(shared=True) | Q(user=request.user if request.user.is_authenticated else None),
-            object_type=object_type,
-            table=table.name,
-            enabled=True,
-        )
-
         # If this is an HTMX request, return only the rendered table HTML
         # If this is an HTMX request, return only the rendered table HTML
         if htmx_partial(request):
         if htmx_partial(request):
             if request.GET.get('embedded', False):
             if request.GET.get('embedded', False):
@@ -208,7 +192,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
         context = {
         context = {
             'model': model,
             'model': model,
             'table': table,
             'table': table,
-            'table_configs': table_configs,
+            'table_configs': get_table_configs(table, request.user),
             'actions': actions,
             'actions': actions,
             'filter_form': self.filterset_form(request.GET) if self.filterset_form else None,
             'filter_form': self.filterset_form(request.GET) if self.filterset_form else None,
             'prerequisite_model': get_prerequisite_model(self.queryset),
             'prerequisite_model': get_prerequisite_model(self.queryset),

+ 12 - 0
netbox/netbox/views/generic/mixins.py

@@ -1,3 +1,6 @@
+from django.shortcuts import get_object_or_404
+
+from extras.models import TableConfig
 from netbox.constants import DEFAULT_ACTION_PERMISSIONS
 from netbox.constants import DEFAULT_ACTION_PERMISSIONS
 from utilities.permissions import get_permission_for_model
 from utilities.permissions import get_permission_for_model
 
 
@@ -47,6 +50,15 @@ class TableMixin:
             request: The current request
             request: The current request
             bulk_actions: Render checkboxes for object selection
             bulk_actions: Render checkboxes for object selection
         """
         """
+
+        # If a TableConfig has been specified, apply it & update the user's saved preference
+        if tableconfig_id := request.GET.get('tableconfig_id'):
+            tableconfig = get_object_or_404(TableConfig, pk=tableconfig_id)
+            if request.user.is_authenticated:
+                table = self.table.__name__
+                request.user.config.set(f'tables.{table}.columns', tableconfig.columns)
+                request.user.config.set(f'tables.{table}.ordering', tableconfig.ordering, commit=True)
+
         table = self.table(data, user=request.user)
         table = self.table(data, user=request.user)
         if 'pk' in table.base_columns and bulk_actions:
         if 'pk' in table.base_columns and bulk_actions:
             table.columns.show('pk')
             table.columns.show('pk')

+ 2 - 0
netbox/netbox/views/generic/object_views.py

@@ -20,6 +20,7 @@ from utilities.forms import ConfirmationForm, restrict_form_fields
 from utilities.htmx import htmx_partial
 from utilities.htmx import htmx_partial
 from utilities.permissions import get_permission_for_model
 from utilities.permissions import get_permission_for_model
 from utilities.querydict import normalize_querydict, prepare_cloned_fields
 from utilities.querydict import normalize_querydict, prepare_cloned_fields
+from utilities.tables import get_table_configs
 from utilities.views import GetReturnURLMixin, get_viewname
 from utilities.views import GetReturnURLMixin, get_viewname
 from .base import BaseObjectView
 from .base import BaseObjectView
 from .mixins import ActionsMixin, TableMixin
 from .mixins import ActionsMixin, TableMixin
@@ -156,6 +157,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
             'base_template': f'{instance._meta.app_label}/{instance._meta.model_name}.html',
             'base_template': f'{instance._meta.app_label}/{instance._meta.model_name}.html',
             'table': table,
             'table': table,
             'table_config': f'{table.name}_config',
             'table_config': f'{table.name}_config',
+            'table_configs': get_table_configs(table, request.user),
             'filter_form': self.filterset_form(request.GET) if self.filterset_form else None,
             'filter_form': self.filterset_form(request.GET) if self.filterset_form else None,
             'actions': actions,
             'actions': actions,
             'tab': self.tab,
             'tab': self.tab,

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox.js.map


+ 2 - 1
netbox/project-static/src/tableConfig.ts

@@ -80,7 +80,8 @@ function handleSubmit(event: Event): void {
         const toast = createToast('danger', 'Error Resetting Table Configuration', res.error);
         const toast = createToast('danger', 'Error Resetting Table Configuration', res.error);
         toast.show();
         toast.show();
       } else {
       } else {
-        location.reload();
+        // Strip any URL query parameters & reload the page
+        window.location.href = window.location.origin + window.location.pathname;
       }
       }
     });
     });
     return;
     return;

+ 17 - 0
netbox/utilities/tables.py

@@ -1,9 +1,13 @@
+from django.apps import apps
+from django.db.models import Q
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
+from core.models import ObjectType
 from netbox.registry import registry
 from netbox.registry import registry
 
 
 __all__ = (
 __all__ = (
+    'get_table_configs',
     'get_table_for_model',
     'get_table_for_model',
     'get_table_ordering',
     'get_table_ordering',
     'linkify_phone',
     'linkify_phone',
@@ -11,6 +15,19 @@ __all__ = (
 )
 )
 
 
 
 
+def get_table_configs(table, user):
+    """
+    Return any available TableConfigs applicable to the given table & user.
+    """
+    TableConfig = apps.get_model('extras', 'TableConfig')
+    return TableConfig.objects.filter(
+        Q(shared=True) | Q(user=user if user.is_authenticated else None),
+        object_type=ObjectType.objects.get_for_model(table.Meta.model),
+        table=table.name,
+        enabled=True,
+    )
+
+
 def get_table_for_model(model, name=None):
 def get_table_for_model(model, name=None):
     name = name or f'{model.__name__}Table'
     name = name or f'{model.__name__}Table'
     try:
     try:

Некоторые файлы не были показаны из-за большого количества измененных файлов