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

Refactor ObjectChildrenView

This commit is contained in:
jeremystretch
2022-06-28 18:14:57 -04:00
parent cd3111ca8d
commit c5770392e3
3 changed files with 53 additions and 34 deletions

View File

@ -24,6 +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
__all__ = ( __all__ = (
'BulkComponentCreateView', 'BulkComponentCreateView',
@ -36,9 +37,9 @@ __all__ = (
) )
class ObjectListView(BaseMultiObjectView): class ObjectListView(BaseMultiObjectView, TableMixin):
""" """
Display multiple objects, all of the same type, as a table. Display multiple objects, all the same type, as a table.
Attributes: Attributes:
filterset: A django-filter FilterSet that is applied to the queryset filterset: A django-filter FilterSet that is applied to the queryset
@ -61,20 +62,6 @@ class ObjectListView(BaseMultiObjectView):
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')
def get_table(self, request, bulk_actions=True):
"""
Return the django-tables2 Table instance to be used for rendering the objects list.
Args:
request: The current request
bulk_actions: Show checkboxes for object selection
"""
table = self.table(self.queryset, user=request.user)
if 'pk' in table.base_columns and bulk_actions:
table.columns.show('pk')
return table
# #
# Export methods # Export methods
# #
@ -159,7 +146,7 @@ class ObjectListView(BaseMultiObjectView):
# Export the current table view # Export the current table view
if request.GET['export'] == 'table': if request.GET['export'] == 'table':
table = self.get_table(request, has_bulk_actions) table = self.get_table(self.queryset, request, has_bulk_actions)
columns = [name for name, _ in table.selected_columns] columns = [name for name, _ in table.selected_columns]
return self.export_table(table, columns) return self.export_table(table, columns)
@ -177,12 +164,11 @@ class ObjectListView(BaseMultiObjectView):
# Fall back to default table/YAML export # Fall back to default table/YAML export
else: else:
table = self.get_table(request, has_bulk_actions) table = self.get_table(self.queryset, request, has_bulk_actions)
return self.export_table(table) return self.export_table(table)
# Render the objects table # Render the objects table
table = self.get_table(request, has_bulk_actions) table = self.get_table(self.queryset, request, has_bulk_actions)
table.configure(request)
# 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 is_htmx(request): if is_htmx(request):

View File

@ -0,0 +1,22 @@
__all__ = (
'TableMixin',
)
class TableMixin:
def get_table(self, data, request, bulk_actions=True):
"""
Return the django-tables2 Table instance to be used for rendering the objects list.
Args:
data: Queryset or iterable containing table data
request: The current request
bulk_actions: Render checkboxes for object selection
"""
table = self.table(data, user=request.user)
if 'pk' in table.base_columns and bulk_actions:
table.columns.show('pk')
table.configure(request)
return table

View File

@ -1,4 +1,5 @@
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
@ -20,6 +21,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
__all__ = ( __all__ = (
'ComponentCreateView', 'ComponentCreateView',
@ -69,23 +71,31 @@ class ObjectView(BaseObjectView):
}) })
class ObjectChildrenView(ObjectView): class ObjectChildrenView(ObjectView, TableMixin):
""" """
Display a table of child objects associated with the parent object. Display a table of child objects associated with the parent object.
Attributes: Attributes:
table: Table class used to render child objects list child_model: The model class which represents the child objects
table: The django-tables2 Table class used to render the child objects list
filterset: A django-filter FilterSet that is applied to the queryset
""" """
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):
""" """
Return a QuerySet of child objects. Return a QuerySet of child objects.
request: The current request Args:
parent: The parent object request: The current request
parent: The parent object
""" """
raise NotImplementedError(f'{self.__class__.__name__} must implement get_children()') raise NotImplementedError(f'{self.__class__.__name__} must implement get_children()')
@ -114,16 +124,16 @@ class ObjectChildrenView(ObjectView):
if self.filterset: if self.filterset:
child_objects = self.filterset(request.GET, child_objects).qs child_objects = self.filterset(request.GET, child_objects).qs
permissions = {} # Determine the available actions
for action in ('change', 'delete'): actions = []
perm_name = get_permission_for_model(self.child_model, action) for action in self.actions:
permissions[action] = request.user.has_perm(perm_name) if request.user.has_perms([
get_permission_for_model(self.child_model, name) for name in self.action_perms[action]
]):
actions.append(action)
table = self.table(self.prep_table_data(request, child_objects, instance), user=request.user) table_data = self.prep_table_data(request, child_objects, instance)
# Determine whether to display bulk action checkboxes table = self.get_table(table_data, request, bool(actions))
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
table.columns.show('pk')
table.configure(request)
# 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 is_htmx(request): if is_htmx(request):
@ -134,8 +144,9 @@ class ObjectChildrenView(ObjectView):
return render(request, self.get_template_name(), { return render(request, self.get_template_name(), {
'object': instance, 'object': instance,
'child_model': self.child_model,
'table': table, 'table': table,
'permissions': permissions, 'actions': actions,
**self.get_extra_context(request, instance), **self.get_extra_context(request, instance),
}) })