Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call django rest API with list of model ids

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)
like image 468
Scott Avatar asked Sep 19 '25 04:09

Scott


1 Answers

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

like image 196
jgadelange Avatar answered Sep 22 '25 13:09

jgadelange