How to tag whole ViewSet in drf_yasg?

3.3k views Asked by At

I have the following ViewSet:

class AuthorViewSet(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer
    permission_classes = [permissions.AllowAny]

    # note that no methods are overridden

I want drf_yasg to generate custom schema such that all action methods will be tagged as Authors.

The documentation says that my options are to either decorate each method by declaring it and using @swagger_auto_schema like so:

class AuthorViewSet(viewsets.ModelViewSet):
    # ...
    @swagger_auto_schema(tags=["Authors"])
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

Or use Django's @method_decorator like so:

@method_decorator(name="list", decorator=swagger_auto_schema(tags=["Authors"]))
class AuthorViewSet(viewsets.ModelViewSet):
    # ...

Both options require tedious repetition which I would like to avoid.

I've also tried to implement my own decorator:

def decorate_viewset_methods(names, decorator):
    if names == "__all__":
        names = [
            "create",
            "retrieve",
            "update",
            "partial_update",
            "destroy",
            "list",
        ]

    def decorate(cls):
        for name in names:
            method = getattr(cls, name)
            setattr(cls, name, decorator(method))
        return cls

    return decorate

But it didn't quite work out.

So my question is how can I decorate all action methods at once?

1

There are 1 answers

2
Aprimus On BEST ANSWER

I ended up using something like this:

first creating a custom auto schema

class CustomAutoSchema(SwaggerAutoSchema):

    def get_tags(self, operation_keys=None):
        tags = self.overrides.get('tags', None) or getattr(self.view, 'my_tags', [])
        if not tags:
            tags = [operation_keys[0]]

        return tags

in your settings file add:

SWAGGER_SETTINGS = {"DEFAULT_AUTO_SCHEMA_CLASS":"path.to.CustomAutoSchema"}

and in your View:

class AuthorViewSet(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer
    permission_classes = [permissions.AllowAny]
    my_tags = ["Authors"]