gorus February 2016

Using django-filter, why do unspecified or invalid lookup types return all results?

Here's a very simple Django Rest Framework/django-filter code example:

class MyModelFilter(django_filters.FilterSet):
    class Meta:
        model = MyModel
        fields = {'my_str_field': ['exact']}

class MyModelList(generics.ListAPIView):
    queryset = MyModel.objects.all()
    filter_class = MyModelFilter

    def get(self, request, format=None):
        items = self.filter_queryset(self.queryset)  # apply filters
        serializer = MyModelSerializer(items, many=True)
        return Response(serializer.data)

When I make this API call, the exact lookup type works as expected, returning matched objects:

/myobjects/?my_str_field=somevalue

If I use icontains, which as you see I did not specify as one of the supported lookup types, all objects are returned, as if the filter wasn't applied:

/myobjects/?my_str_field__icontains=this_can_be_anything

Furthermore, I can even use an invalid lookup type and there will be no error, with, again, all objects returned:

 /myobjects/?my_str_field__this_can_be_anything=this_can_be_anything

This can obviously be misleading because a front-end developer who doesn't have access to the back-end code can happily think everything is fine and use the returned objects. I would expect, if not an error, at least an empty result set for the latter two cases. What am I doing wrong?

UPDATE: It appears that I should be using the strictness setting like so:

from django_filters.filterset import STRICTNESS
class MyModelFilter(django_filters.FilterSet):
    # throw an exception on errors instead of returning empty results
    strict = STRICTNESS.RAISE_VALIDATION_ERROR
    class Meta:
        model = MyModel
        fields = {'my_str_field': ['exact']}

Unfortunately, this still doesn't result in an error, so my original

Answers


Håken Lid February 2016

If the server doesn't recognize a query string parameter, the typical behavior is to ignore that parameter. There's no standard or rfc that specifies how to handle unexpected query string parameters. But very many websites and web frameworks will liberally accept requests, and not perform any validation to reject requests that contain superfluous or misspelled query parameters.

In other words, this is not specific for Django Rest Framework.

This feature makes ajax cache busting possible. jQuery will add a parameter called _ with a random value to every single ajax request to make sure that the request has a unique url and is not cached anywhere. This would not work if the server returned an error on receiving an unexpected query parameter.

Post Status

Asked in February 2016
Viewed 2,710 times
Voted 12
Answered 1 times

Search




Leave an answer