How can I stop the django REST structure to show all records if the request parameter is incorrect

I use the Django REST Framework, and I use filters to filter a set of requests.

http://www.django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters

like this

http://example.com/api/products/4675/?category=clothing&max_price=10.00

But I saw that if there is an error in the filters or the query parameters do not exist, then it displays all very bad results.

I do not want any results if there is a problem with the query parameters, because sometimes I do not know if this works or not.

EDIT

This is my code.

 class userFilter(django_filters.FilterSet): strict = True class Meta: model = User fields = ('is_active', 'is_archived', 'age') 

REST

 class UserListCreateView(generics.ListCreateAPIView): queryset = User.objects.filter(is_archived=False) ordering_fields = ('is_active') filter_class = userFilter 

These are REST settings

 REST_FRAMEWORK = { 'DEFAULT_MODEL_SERIALIZER_CLASS': 'rest_framework.serializers.HyperlinkedModelSerializer', 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_FILTER_BACKENDS': ( 'rest_framework.filters.DjangoFilterBackend', 'rest_framework.filters.SearchFilter', 'rest_framework.filters.OrderingFilter', ), # 'PAGINATE_BY': 1, 'PAGINATE_BY_PARAM': 'page_size', 'MAX_PAGINATE_BY': 100, 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', ) } 
+5
source share
3 answers

If you are using DjangoFilterBackend , check out the strict Non-Meta option .

A strict parameter determines whether results are returned when an invalid value is specified by the user for any filter field. From default, strict is set to True, meaning that an empty request if any field contains an invalid value. You can ease this behavior by setting a strict False value that effectively ignores the filter field if its value is invalid.

Filter:

 from django_filters.filterset import FilterSet class UserFilter(FilterSet): strict = True class Meta: model = User fields = ['username'] 

Settings: (assuming you installed django-filter )

 REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',) } 

Now, if someone does:

 http://api.example.com/users/?username=myuser&badfilter=1 

... it will return an empty list since badfilter does not exist.

As the FilterSet automatically set to strict=True , I get the feeling that you are not using DjangoFilterBackend .

+4
source

The marked answer did not help me. I solved this by overriding the get method:

 class UserListCreateView(generics.ListCreateAPIView): queryset = User.objects.filter(is_archived=False) ordering_fields = ('is_active') filter_class = userFilter @staticmethod def is_valid_query_params(query_params): # do validations here ... def get(self, request, *args, **kwargs): if not self.is_valid_query_params(request.query_params): return Response([]) # send empty response return super(UserListCreateView, self).get(request, *args, **kwargs) 
+1
source

Your specific problem arises from the fact that the parameters that you call in your GET request are not defined in your UserFilter . Thus, only the following parameters will be taken into account from DRF:

 fields = ('is_active', 'is_archived', 'age') 

In addition, strict controls the parameter query parameter , if the parameter itself exists . for instance

 GET mydomain.com/resource_path?whatever=blabla 

returns the entire set of requests, which, in my opinion, is something wrong, at least not compatible with REST.

In the end, I wrote a small method to manually check if the request parameters passed in the request really exist.

0
source

Source: https://habr.com/ru/post/1207864/


All Articles