diff --git a/netbox/core/api/schema.py b/netbox/core/api/schema.py index 1502592b06..d06d1d3bfa 100644 --- a/netbox/core/api/schema.py +++ b/netbox/core/api/schema.py @@ -13,6 +13,7 @@ build_choice_field, build_media_type_object, build_object_type, + get_doc, is_serializer, ) from drf_spectacular.types import OpenApiTypes @@ -232,3 +233,31 @@ def _get_request_body(self, direction='request'): 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."