diff --git a/docs/plugins/development/views.md b/docs/plugins/development/views.md index e12f32bad..45d7064cf 100644 --- a/docs/plugins/development/views.md +++ b/docs/plugins/development/views.md @@ -82,23 +82,25 @@ class ThingEditView(ObjectEditView): Below are the class definitions for NetBox's object views. These views handle CRUD actions for individual objects. The view, add/edit, and delete views each inherit from `BaseObjectView`, which is not intended to be used directly. ::: netbox.views.generic.base.BaseObjectView + options: + members: + - get_queryset + - get_object + - get_extra_context ::: netbox.views.generic.ObjectView options: members: - - get_object - get_template_name ::: netbox.views.generic.ObjectEditView options: members: - - get_object - alter_object ::: netbox.views.generic.ObjectDeleteView options: - members: - - get_object + members: false ::: netbox.views.generic.ObjectChildrenView options: @@ -111,6 +113,10 @@ Below are the class definitions for NetBox's object views. These views handle CR Below are the class definitions for NetBox's multi-object views. These views handle simultaneous actions for sets objects. The list, import, edit, and delete views each inherit from `BaseMultiObjectView`, which is not intended to be used directly. ::: netbox.views.generic.base.BaseMultiObjectView + options: + members: + - get_queryset + - get_extra_context ::: netbox.views.generic.ObjectListView options: diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index 80b94d6c2..ba5947364 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -38,6 +38,7 @@ A new `PluginMenu` class has been introduced, which enables a plugin to inject a * [#9072](https://github.com/netbox-community/netbox/issues/9072) - Enable registration of tabbed plugin views for core NetBox models * [#9880](https://github.com/netbox-community/netbox/issues/9880) - Introduce `django_apps` plugin configuration parameter * [#10314](https://github.com/netbox-community/netbox/issues/10314) - Move `clone()` method from NetBoxModel to CloningMixin +* [#10739](https://github.com/netbox-community/netbox/issues/10739) - Introduce `get_queryset()` method on generic views ### Other Changes diff --git a/netbox/netbox/views/generic/base.py b/netbox/netbox/views/generic/base.py index 3ad3bcf67..8e49ea62f 100644 --- a/netbox/netbox/views/generic/base.py +++ b/netbox/netbox/views/generic/base.py @@ -1,18 +1,40 @@ +from django.core.exceptions import ImproperlyConfigured from django.shortcuts import get_object_or_404 from django.views.generic import View from utilities.views import ObjectPermissionRequiredMixin -class BaseObjectView(ObjectPermissionRequiredMixin, View): +class BaseView(ObjectPermissionRequiredMixin, View): + queryset = 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() + + +class BaseObjectView(BaseView): """ - Base view class for reusable generic views. + 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 get_object(self, **kwargs): @@ -35,16 +57,15 @@ class BaseObjectView(ObjectPermissionRequiredMixin, View): return {} -class BaseMultiObjectView(ObjectPermissionRequiredMixin, View): +class BaseMultiObjectView(BaseView): """ - Base view class for reusable generic views. + Base class for generic views which display or manipulate multiple objects. Attributes: queryset: Django QuerySet from which the object(s) will be fetched 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