diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index 910e25b9a..122ecb18b 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -71,11 +71,14 @@ Two new webhook trigger events have been introduced: `job_start` and `job_end`. * [#11968](https://github.com/netbox-community/netbox/issues/11968) - Add navigation menu buttons to create device & VM components * [#12068](https://github.com/netbox-community/netbox/issues/12068) - Enable generic foreign key relationships from jobs to NetBox objects * [#12085](https://github.com/netbox-community/netbox/issues/12085) - Add a file source view for reports +* [#12218](https://github.com/netbox-community/netbox/issues/12218) - Provide more relevant API endpoint descriptions in schema ### Bug Fixes (From Beta2) * [#12149](https://github.com/netbox-community/netbox/issues/12149) - Fix OpenAPI schema warnings relating to enum collisions +* [#12195](https://github.com/netbox-community/netbox/issues/12195) - Fix exception when setting IP address role to null via REST API * [#12256](https://github.com/netbox-community/netbox/issues/12256) - Fix OpenAPI schema warnings relating to nested serializers +* [#12278](https://github.com/netbox-community/netbox/issues/12278) - Fix schema warnings related to IPAddressField * [#12288](https://github.com/netbox-community/netbox/issues/12288) - Include `servers` definition in OpenAPI spec * [#12299](https://github.com/netbox-community/netbox/issues/12299) - Fix object list widget support for filtering by multiple values diff --git a/netbox/core/api/schema.py b/netbox/core/api/schema.py index 1502592b0..d06d1d3bf 100644 --- a/netbox/core/api/schema.py +++ b/netbox/core/api/schema.py @@ -13,6 +13,7 @@ from drf_spectacular.plumbing import ( build_choice_field, build_media_type_object, build_object_type, + get_doc, is_serializer, ) from drf_spectacular.types import OpenApiTypes @@ -232,3 +233,31 @@ class NetBoxAutoSchema(AutoSchema): if request_body_required: request_body['required'] = request_body_required return request_body + + def get_description(self): + """ + Return a string description for the ViewSet. + """ + + # If a docstring is provided, use it. + if self.view.__doc__: + return get_doc(self.view.__class__) + + # When the action method is decorated with @action, use the docstring of the method. + action_or_method = getattr(self.view, getattr(self.view, 'action', self.method.lower()), None) + if action_or_method and action_or_method.__doc__: + return get_doc(action_or_method) + + # Else, generate a description from the class name. + return self._generate_description() + + def _generate_description(self): + """ + Generate a docstring for the method. It also takes into account whether the method is for list or detail. + """ + model_name = self.view.queryset.model._meta.verbose_name + + # Determine if the method is for list or detail. + if '{id}' in self.path: + return f"{self.method.capitalize()} a {model_name} object." + return f"{self.method.capitalize()} a list of {model_name} objects."