Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering on action decorator - Django Rest Framework

I am trying to filter data using a decorator action on Django Rest Framework, it works perfect if I use the global queryset (get_queryset() function) but I need to use it in a separate function.

I am using django-filter to perform it. This is the code.

My view:

class ShippingAPI(viewsets.ModelViewSet):
    serializer_class = ShippingSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('origin__department', 'destination__department', 'first_collection_date', 'last_collection_date', 'vehicle')

The override (action)

@action(detail=False, methods=['GET'])
def filter_shippings(self, request, **kwargs):
    queryset = Shipping.objects.filter(status=2, orderStatus=0)
    serializer = SearchShippingSerializer(queryset, many=True) #Yes, I am using another serializer, but it is solved,I use diferent if it is necesary
    return Response(serializer.data)

After use my url 'api/filter_shipping/(all filters here)', this still return all the data without the filters I am requesting.

Thanks for your help

like image 812
Jeremias Enriquez Avatar asked Nov 19 '18 04:11

Jeremias Enriquez


2 Answers

Add filter_queryset function like this. It worked for me. Found the solution in Django-filters issues: https://github.com/carltongibson/django-filter/issues/967 .

@action(detail=False, methods=['GET'])
def filter_shippings(self, request, **kwargs):
    queryset = self.filter_queryset(self.get_queryset()).filter(status=2, orderStatus=0)
    serializer = SearchShippingSerializer(queryset, many=True) #Yes, I am using another serializer, but it is solved,I use diferent if it is necesary
    return Response(serializer.data)
like image 190
jplattus Avatar answered Nov 27 '22 20:11

jplattus


You can filter on the result of get_queryset to limit your results.

@action(detail=False, methods=['GET'])
def filter_shippings(self, request, **kwargs):
    queryset = self.get_queryset().filter(status=2, orderStatus=0)
    serializer = SearchShippingSerializer(queryset, many=True) #Yes, I am using another serializer, but it is solved,I use diferent if it is necesary
    return Response(serializer.data)

Edit: You can create a custom filter do the filtering as needed. Here is the example from django-filter's docs.

import django_filters

class ProductFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['name', 'price', 'manufacturer']

def product_list(request):
    filter = ProductFilter(request.GET, queryset=Product.objects.all())
    return render(request, 'my_app/template.html', {'filter': filter})
like image 31
schillingt Avatar answered Nov 27 '22 21:11

schillingt