Search code examples
pythondjangodjango-rest-frameworkswaggerdjango-rest-swagger

Django swagger- How to disable DjangoFilterBackend query filters from delete, put methods?


I've created an AssetsFilter class:

from django_filters import Filter
from django_filters import rest_framework as filters
from django_filters.fields import Lookup

from .models import Assets


class MyListFilter(Filter):
    def filter(self, qs, value):
        value_list = value.split(',')
        return super(ListFilter, self).filter(qs, Lookup(value_list, 'in'))


class AssetsFilter(filters.FilterSet):
    name = filters.CharFilter(lookup_expr='icontains', help_text=u'Filter by name')
    criticality = MyListFilter(name='critical', help_text=u'Filter by_id')

    class Meta:
        model = Assets
        fields = ['name', 'criticality ']

Now I'm using this filter in my Viewset as follows:

from .serializers import AssetSerializers
from .filters import AssetsFilter


class AssetViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    """
    queryset = Assets.objects.all()
    serializer_class = AssetSerializers
    filter_backends = (DjangoFilterBackend,)
    filter_class = AssetsFilter
    http_method_names = ['get', 'post', 'put', 'delete']

    def list(self, request):
        """
        Returns a list of Asset.
        """
        return super(AssetViewSet, self).list(request)

    def create(self, request):
        """
        Creates a new Asset.<br>
        """
        return super(AssetViewSet, self).create(request)

    def destroy(self, request, pk=None):
        """
        Deletes a Asset.
        """
        return super(AssetViewSet, self).destroy(request, pk=pk)

    def retrieve(self, request, pk=None):
        """
        Returns a Asset with id={id}
        """
        return super(AssetViewSet, self).retrieve(request, pk=pk)

    def update(self, request, pk=None, *args, **kwargs):
        """
        Updates an existing Asset.<br>
        """
        return super(AssetViewSet, self).update(request, pk=pk, *args, **kwargs)

When the swagger documentation is created, the filter fields appear in GET (list), GET (retrieve) as expected, but they also appear in the POST, PUT, PATCH and DELETE where they shouldn't be.

How can I disable those parameters from appearing in the latest version of django-rest-swagger and DRF?


Solution

  • If you don't want to Add Schema Manually(Every time) then Here is the solution: auto_schema.py

    from rest_framework.schemas import AutoSchema
    from django.utils.six.moves.urllib import parse as urlparse
    import coreapi, coreschema
    
    
    class CustomSchema(AutoSchema):
        def get_link(self, path, method, base_url):
            fields = self.get_path_fields(path, method)
            fields += self.get_serializer_fields(path, method)
            fields += self.get_pagination_fields(path, method)
            if self.view.action in ['list']:
                fields += self.get_filter_fields(path, method)
    
            manual_fields = self.get_manual_fields(path, method)
            fields = self.update_fields(fields, manual_fields)
    
            if fields and any([field.location in ('form', 'body') for field in fields]):
                encoding = self.get_encoding(path, method)
            else:
                encoding = None
    
            description = self.get_description(path, method)
    
            if base_url and path.startswith('/'):
                path = path[1:]
    
            return coreapi.Link(
                url=urlparse.urljoin(base_url, path),
                action=method.lower(),
                encoding=encoding,
                fields=fields,
                description=description
            )
    

    views.py

    class MyUserViewSet(viewsets.ModelViewSet):
        """
        API endpoint that allows users to be viewed or edited.
    
        """
        model = MyUser
        serializer_class = MyUserSerializer
        queryset = MyUser.objects.all()
        filter_backends = (DjangoFilterBackend, OrderingFilter)
        filter_class = MyUserFilter
        ordering_fields = ('last_name', 'first_name', 'email', 'is_active')
        ordering = ('last_name', 'first_name')
        permission_classes = (IsAuthenticated,)
        schema = CustomSchema()