diff --git a/netbox/netbox/views/generic/base.py b/netbox/netbox/views/generic/base.py index 8e49ea62f..778a54e10 100644 --- a/netbox/netbox/views/generic/base.py +++ b/netbox/netbox/views/generic/base.py @@ -4,9 +4,22 @@ from django.views.generic import View from utilities.views import ObjectPermissionRequiredMixin +__all__ = ( + 'BaseObjectView', + 'BaseMultiObjectView', +) -class BaseView(ObjectPermissionRequiredMixin, View): + +class BaseObjectView(ObjectPermissionRequiredMixin, View): + """ + Base class for generic views which display or manipulate a single object. + + Attributes: + queryset: Django QuerySet from which the object(s) will be fetched + template_name: The name of the HTML template file to render + """ queryset = None + template_name = None def dispatch(self, request, *args, **kwargs): self.queryset = self.get_queryset(request) @@ -14,7 +27,7 @@ class BaseView(ObjectPermissionRequiredMixin, View): def get_queryset(self, request): """ - Return the base queryset for the view. By default, this returns self.queryset.all(). + Return the base queryset for the view. By default, this returns `self.queryset.all()`. Args: request: The current request @@ -26,17 +39,6 @@ class BaseView(ObjectPermissionRequiredMixin, View): ) return self.queryset.all() - -class BaseObjectView(BaseView): - """ - Base class for generic views which display or manipulate a single object. - - Attributes: - queryset: Django QuerySet from which the object(s) will be fetched - template_name: The name of the HTML template file to render - """ - template_name = None - def get_object(self, **kwargs): """ Return the object being viewed or modified. The object is identified by an arbitrary set of keyword arguments @@ -57,7 +59,7 @@ class BaseObjectView(BaseView): return {} -class BaseMultiObjectView(BaseView): +class BaseMultiObjectView(ObjectPermissionRequiredMixin, View): """ Base class for generic views which display or manipulate multiple objects. @@ -66,9 +68,28 @@ class BaseMultiObjectView(BaseView): table: The django-tables2 Table class used to render the objects list template_name: The name of the HTML template file to render """ + queryset = None table = None template_name = None + def dispatch(self, request, *args, **kwargs): + self.queryset = self.get_queryset(request) + return super().dispatch(request, *args, **kwargs) + + def get_queryset(self, request): + """ + Return the base queryset for the view. By default, this returns `self.queryset.all()`. + + Args: + request: The current request + """ + if self.queryset is None: + raise ImproperlyConfigured( + f"{self.__class__.__name__} does not define a queryset. Set queryset on the class or " + f"override its get_queryset() method." + ) + return self.queryset.all() + def get_extra_context(self, request): """ Return any additional context data to include when rendering the template.