2

I have for the moment a GET request where I have to send a body as a parameter but as in front it is not possible to make a GET request with a body I would like to pass my parameters as query parameters in the URL . How can I do this with the code I currently have?

My serializer class:

@dataclass
class PlantLinkParams:
    plant_id: int
    link: str

class LnkPlantPlantByLinkSerializer(serializers.Serializer):
    plant_id = serializers.IntegerField()
    link = serializers.CharField()

    def create(self, validated_data):
        return PlantLinkParams(**validated_data)

My view class :

class PlantLinkAPIView(APIView):
    permission_classes = (AllowAnonymous,)
    queryset = LnkPlantPlant.objects.prefetch_related("plant", "plant_associated")

    def get(self, request):
        params_serializer = LnkPlantPlantByLinkSerializer(data=request.data)
        params_serializer.is_valid(raise_exception=True)
        params = params_serializer.save()
        data = self.getAllPlantAssociatedByLink(params)
        serializer = ReadLnkPlantPlantSerializer(instance=data, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def getAllPlantAssociatedByLink(self, params: PlantLinkParams):
        data = []
        queryset = (
            LnkPlantPlant.objects.filter(
                plant=params.plant_id,
                link=params.link,
            )
        )
        for entry in queryset:
            data.append(entry)
        return data

1 Answer 1

1

You could do something simpler using a ListAPIView:

class PlantLinkAPIView(ListAPIView):
    permission_classes = (AllowAnonymous,)
    serializer_class = ReadLnkPlantPlantSerializer

    def get_queryset(self):
        # Retrieve the query parameters (?plant_id=xxx&link=yyy)
        try:
            plant_id = int(self.request.GET.get('plant_id'))
        except (ValueError, TypeError):
            # Prevents plant_id to be set if not a valid integer
            plant_id = None
        link = self.request.GET.get('link')

        params = {}
        if plant_id:
            params['plant__id'] = plant_id
        if link:
            params['link'] = link

        # Only filtering the queryset if one of the params is set
        if params:
            return LnkPlantPlant.objects.filter(**params)
        return LnkPlantPlant.objects.all()

You don't need more than that to get your view working.

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

7 Comments

Thank you very much ! I'm new to Django, I'm taking over someone's project so I was wondering if your code with the params above makes it possible to have query parameters in url For example, I would like to have something like this: /api/lnk/plant/plants?plant_id=3&link=good
@PierroTH It does, the query parameters are retrieved with self.request.GET.get(param_name). I'm also making sure that plant_id is an integer and only filter the queryset with the params that have been set correctly.
Thank you for your help really! When I test on postman, it puts me "GET method not allowed"
@PierroTH Your view probably still inherits from APIView. GET is handled by the ListAPIView.
Ohh yes it's good thank you very much for your help it's very kind! I still have a lot to learn in Django and Dajngo Rest Framework
|

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.