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

Move actions determination to a mixin

jeremystretch 3 лет назад
Родитель
Сommit
cdcb77dea8

+ 5 - 19
netbox/netbox/views/generic/bulk_views.py

@@ -24,7 +24,7 @@ from utilities.htmx import is_htmx
 from utilities.permissions import get_permission_for_model
 from utilities.permissions import get_permission_for_model
 from utilities.views import GetReturnURLMixin
 from utilities.views import GetReturnURLMixin
 from .base import BaseMultiObjectView
 from .base import BaseMultiObjectView
-from .mixins import TableMixin
+from .mixins import ActionsMixin, TableMixin
 
 
 __all__ = (
 __all__ = (
     'BulkComponentCreateView',
     'BulkComponentCreateView',
@@ -37,7 +37,7 @@ __all__ = (
 )
 )
 
 
 
 
-class ObjectListView(BaseMultiObjectView, TableMixin):
+class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
     """
     """
     Display multiple objects, all the same type, as a table.
     Display multiple objects, all the same type, as a table.
 
 
@@ -51,13 +51,6 @@ class ObjectListView(BaseMultiObjectView, TableMixin):
     template_name = 'generic/object_list.html'
     template_name = 'generic/object_list.html'
     filterset = None
     filterset = None
     filterset_form = None
     filterset_form = None
-    actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete')
-    action_perms = defaultdict(set, **{
-        'add': {'add'},
-        'import': {'add'},
-        'bulk_edit': {'change'},
-        'bulk_delete': {'delete'},
-    })
 
 
     def get_required_permission(self):
     def get_required_permission(self):
         return get_permission_for_model(self.queryset.model, 'view')
         return get_permission_for_model(self.queryset.model, 'view')
@@ -134,12 +127,7 @@ class ObjectListView(BaseMultiObjectView, TableMixin):
             self.queryset = self.filterset(request.GET, self.queryset).qs
             self.queryset = self.filterset(request.GET, self.queryset).qs
 
 
         # Determine the available actions
         # Determine the available actions
-        actions = []
-        for action in self.actions:
-            if request.user.has_perms([
-                get_permission_for_model(model, name) for name in self.action_perms[action]
-            ]):
-                actions.append(action)
+        actions = self.get_permitted_actions(request.user)
         has_bulk_actions = any([a.startswith('bulk_') for a in actions])
         has_bulk_actions = any([a.startswith('bulk_') for a in actions])
 
 
         if 'export' in request.GET:
         if 'export' in request.GET:
@@ -176,15 +164,13 @@ class ObjectListView(BaseMultiObjectView, TableMixin):
                 'table': table,
                 'table': table,
             })
             })
 
 
-        context = {
+        return render(request, self.template_name, {
             'model': model,
             'model': model,
             'table': table,
             'table': table,
             'actions': actions,
             'actions': actions,
             'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None,
             'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None,
             **self.get_extra_context(request),
             **self.get_extra_context(request),
-        }
-
-        return render(request, self.template_name, context)
+        })
 
 
 
 
 class BulkCreateView(GetReturnURLMixin, BaseMultiObjectView):
 class BulkCreateView(GetReturnURLMixin, BaseMultiObjectView):

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

@@ -1,8 +1,33 @@
+from collections import defaultdict
+
+from utilities.permissions import get_permission_for_model
+
 __all__ = (
 __all__ = (
     'TableMixin',
     'TableMixin',
 )
 )
 
 
 
 
+class ActionsMixin:
+    actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete')
+    action_perms = defaultdict(set, **{
+        'add': {'add'},
+        'import': {'add'},
+        'bulk_edit': {'change'},
+        'bulk_delete': {'delete'},
+    })
+
+    def get_permitted_actions(self, user, model=None):
+        """
+        Return a tuple of actions for which the given user is permitted to do.
+        """
+        model = model or self.queryset.model
+        return [
+            action for action in self.actions if user.has_perms([
+                get_permission_for_model(model, name) for name in self.action_perms[action]
+            ])
+        ]
+
+
 class TableMixin:
 class TableMixin:
 
 
     def get_table(self, data, request, bulk_actions=True):
     def get_table(self, data, request, bulk_actions=True):

+ 6 - 14
netbox/netbox/views/generic/object_views.py

@@ -1,5 +1,4 @@
 import logging
 import logging
-from collections import defaultdict
 from copy import deepcopy
 from copy import deepcopy
 
 
 from django.contrib import messages
 from django.contrib import messages
@@ -21,7 +20,7 @@ from utilities.permissions import get_permission_for_model
 from utilities.utils import get_viewname, normalize_querydict, prepare_cloned_fields
 from utilities.utils import get_viewname, normalize_querydict, prepare_cloned_fields
 from utilities.views import GetReturnURLMixin
 from utilities.views import GetReturnURLMixin
 from .base import BaseObjectView
 from .base import BaseObjectView
-from .mixins import TableMixin
+from .mixins import ActionsMixin, TableMixin
 
 
 __all__ = (
 __all__ = (
     'ComponentCreateView',
     'ComponentCreateView',
@@ -71,7 +70,7 @@ class ObjectView(BaseObjectView):
         })
         })
 
 
 
 
-class ObjectChildrenView(ObjectView, TableMixin):
+class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
     """
     """
     Display a table of child objects associated with the parent object.
     Display a table of child objects associated with the parent object.
 
 
@@ -79,15 +78,13 @@ class ObjectChildrenView(ObjectView, TableMixin):
         child_model: The model class which represents the child objects
         child_model: The model class which represents the child objects
         table: The django-tables2 Table class used to render the child objects list
         table: The django-tables2 Table class used to render the child objects list
         filterset: A django-filter FilterSet that is applied to the queryset
         filterset: A django-filter FilterSet that is applied to the queryset
+        actions: Supported actions for the model. When adding custom actions, bulk action names must
+            be prefixed with `bulk_`. Default actions: add, import, export, bulk_edit, bulk_delete
+        action_perms: A dictionary mapping supported actions to a set of permissions required for each
     """
     """
     child_model = None
     child_model = None
     table = None
     table = None
     filterset = None
     filterset = None
-    actions = ('bulk_edit', 'bulk_delete')
-    action_perms = defaultdict(set, **{
-        'bulk_edit': {'change'},
-        'bulk_delete': {'delete'},
-    })
 
 
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         """
         """
@@ -125,12 +122,7 @@ class ObjectChildrenView(ObjectView, TableMixin):
             child_objects = self.filterset(request.GET, child_objects).qs
             child_objects = self.filterset(request.GET, child_objects).qs
 
 
         # Determine the available actions
         # Determine the available actions
-        actions = []
-        for action in self.actions:
-            if request.user.has_perms([
-                get_permission_for_model(self.child_model, name) for name in self.action_perms[action]
-            ]):
-                actions.append(action)
+        actions = self.get_permitted_actions(request.user, model=self.child_model)
 
 
         table_data = self.prep_table_data(request, child_objects, instance)
         table_data = self.prep_table_data(request, child_objects, instance)
         table = self.get_table(table_data, request, bool(actions))
         table = self.get_table(table_data, request, bool(actions))