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?
The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.
query_params is a more correctly named synonym for request. GET . For clarity inside your code, we recommend using request. query_params instead of the Django's standard request.
queryset - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set read_only=True . many - If applied to a to-many relationship, you should set this argument to True .
The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the . get_queryset() method. Overriding this method allows you to customize the queryset returned by the view in a number of different ways.
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()
Specifying a CustomSchema for every model is not necessary. It is possible to override the DjangoFilterBackend and prevent it from adding the schema fields for some specified actions:
class MyDjangoFilterBackend(DjangoFilterBackend):
def get_schema_fields(self, view):
# Customize according to your need here.
if view.action not in ["list"]:
return []
return super().get_schema_fields(view)
in settings.py :
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'api.filter_backends.MyDjangoFilterBackend'
),
'DEFAULT_PAGINATION_CLASS': 'api.pagination.MyPagination',
'PAGE_SIZE': 20
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With