Django 4 REST framework JSON POST request filter

Question:

I have this API where I need to filter some data. My user will pass a JSON containing several instances that I need to return to them if there existis or not on my database. But I don’t know how I can make Django 4 make several POST requests within the same JSON (I guess since they would be only getting information this would be several "GET" requests, but I need to make them in a POST). Thoughts on how should I do it? I don’t even know how to start.

For example, the POST request could be:


[
    {
        "name": "media1"
    },
    {
        "name": "media2"
    },
    {
        "name": "media3"
    }
]

And if I had medias 1 and 3 but not 2, the API would return the following:

[
    {
        "id": 0,
        "name": "media1"
    },
    {
        None
    },
    {
        "id": 1,
        "name": "media3"
    }
]

This is my current viewset. I have implemented a filter that works only for one GET request at a time:

class MediasViewSet(viewsets.ModelViewSet):
    queryset = Media.objects.all().order_by('name')
    serializer_class = MediaSerializer
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
        
    def get_queryset(self, *args, **kwargs):
        print(self.request)
        queryset = super().get_queryset()
        if(self.request.data.__contains__("name")):
            query = self.request.data['name']
        
            if query:
                queryset = Media.objects.filter(name=query)

        return queryset

This is my media model:

class Media(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=45)

    def __str__(self):
        return self.name

And my serializer:

class MediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Mediafields = ['id', 'name', 'processed_status']
Asked By: JOY

||

Answers:

After struggling for a bit, I managed to find a solution. Here is what I’ve made:

I created another View called CheckMediasAPIView and imported CreateAPIView so I could rewrite the post method. Then, I used the reduce method, using the OR logic operator and the filter for each name. This is the result:

class CheckMediasAPIView(CreateAPIView):

    def post(self, request, *args, **kwargs):
        q = request.data["list"]
        query = reduce(operator.or_, (Q(name__contains = item["name"]) for item in q))
        result = Media.objects.filter(query).values()
        return Response(result)
Answered By: JOY
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.