4

I'm trying to figure out the best way to go about querying an endpoint for specific models with a list of those model ids. I know that I can query the detail endpoint using the id in the url (/markers/{id}), but I'd like to be able to post multiple ids at once and receive data from the model instances with those ids. As of right now, I created a custom APIView seen below (MarkerDetailsList) where I essentially just post a list of ids and define a custom post method to parse and lookup the ids in the db, but I'm finding it hard to believe this is the best way to accomplish this. Is there a way to achieve the same thing using the viewset? I've checked the documentation and searched around and cant seem to find anything. Any suggestions?

class MarkerViewSet(viewsets.ModelViewSet):
    permission_classes = [permissions.AllowAny]
    authentication_classes = ()
    queryset = Marker.objects.all()
    serializer_class = MarkerSerializer

class MarkerDetailList(APIView):
    queryset = Marker.objects.all()
    serializer_class = MarkerSerializer
    permission_classes = [permissions.AllowAny]
    authentication_classes = (JSONWebTokenAuthentication, )

    def post(self, request):
        ids = request.data['mapIds']
        markers = Marker.objects.filter(id__in=ids)
        serializer = MarkerSerializer(markers, many=True)
        return Response(serializer.data)

1 Answer 1

3

You could use a Filter and FilterSet for this. (Wrote part of the code, then found https://stackoverflow.com/a/24042182/2354734)

class ListFilter(django_filters.Filter):
    def filter(self, qs, value):
        if value not in (None, ''):
            integers = [int(v) for v in value.split(',')]
            return qs.filter(**{'%s__%s'%(self.name, self.lookup_type):integers})
        return qs  

class MarkerFilter(django_filters.FilterSet):
    ids = django_filters.NumberFilter(name="id", lookup_type='in')

    class Meta:
        model = Marker
        fields = ['ids']

class MarkerViewSet(viewsets.ModelViewSet):
    queryset = Marker.objects.all()
    serializer_class = MarkerSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = MarkerFilter

When you now retrieven on /markers/?ids=1,2,3,4

Sign up to request clarification or add additional context in comments.

1 Comment

Why is ListFilter there if it's not used?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.