Home > Software engineering >  Django APIView: how to display calculated value
Django APIView: how to display calculated value

Time:01-06

I have to display a calculated value in APIVIEW, but I can't figure out how to set up the view, it's giving me an error.

The code, that returns a simple JSON is working fine:

def protein_coverage(request, protein_id):
    try:
        proteins = Protein.objects.filter(protein=protein_id)
        domain_length = 0
    
        coverage = domain_length / protein_length
        

    except Protein.DoesNotExist:
        return HttpResponse({'message': 'This Protein does not exist'}, status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':

        serializer = ProteinCoverageSerializer(coverage)
        return JsonResponse(serializer.data,safe=False)

I tried this for the APIView:

class ProteinCoverage(generics.RetrieveAPIView):
    serializer_class = ProteinCoverageSerializer

    def get_queryset(self):
        pk = self.kwargs['protein_id']
        proteins = Protein.objects.filter(protein=pk)
        domain_length = 0
    
        coverage = domain_length / protein_length
        return coverage

But it's giving me an error:

Expected view ProteinCoverage to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.

I'm not sure, which API is suitable for this situation and how to pass a single variable to it.

I also checked the documentation, but it's not clear. How do I convert this JsonResponse to APIView?

CodePudding user response:

You can simply do it with APIView:

from rest_framework.response import Response
from rest_framework.views import APIView

class ProteinCoverageView(APIView):

    def get(self, request, protein_id):
        try:
            proteins = Protein.objects.filter(protein=protein_id)
            domain_length = 0
        
            coverage = domain_length / protein_length
        
        except Protein.DoesNotExist:
            return Response({'message': 'This Protein does not exist'}, status=status.HTTP_404_NOT_FOUND)
        
        
        serializer = ProteinCoverageSerializer(coverage)
        return Response(serializer.data)

CodePudding user response:

You have to use lookup_fields. Refer docs

CodePudding user response:

Here is the equivalent solution using APIView of restframewok.

from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView

class ProteinCoverageView(APIView):
    def get(self, request, protein_id):
        try:
            proteins = Protein.objects.get(protein=protein_id) # using get() not filter as get() raise exception if no data found.
            domain_length = 0
            coverage = domain_length / protein_length
        except Protein.DoesNotExist:
            return Response({'message': 'This Protein does not exist'}, status=status.HTTP_404_NOT_FOUND)

        serializer = ProteinCoverageSerializer(coverage)
        return Response(serializer.data)
  • Related