Search code examples
python-3.xdjangodjango-rest-frameworkhttp-post

How do make some computation on my POST request data in Django?


I am trying to send a POST request to my Django backend ie djangorestframework, rest api, and I am trying to get the data from this request and make some computation and send it back to the client.

I get this error: File "/Users/lambdainsphere/seminar/backend/seminar/api/evaluator.py", line 12, in evaluate operand, op, operand2 = exp ValueError: too many values to unpack (expected 3) Here's my view:

@api_view(['POST'])
def compute_linear_algebra_expression(request):
    """
    Given a Linear Algebra expression this view evaluates it.

    @param request: Http POST request
    @return: linear algbera expression
    """
    serializer = LinearAlgebraSerializer(data=request.data)
    
    if serializer.is_valid():
        serializer.save()
        data = serializer.data
        algebra_expr = data['expression']
        #algebra_expr = tuple(algebra_expr)
        print(algebra_expr)
        algebra_expr = evaluate(algebra_expr)
        return Response({"expression":algebra_expr}, status=status.HTTP_201_CREATED)

    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

here is my evaluator: it consumes a python3 tuple:

def evaluate(exp):
    """
    Evaluate a Linea Algebra expression.
    """
    operand, op, operand2 = exp
    if isinstance(operand, Vec) and op == '+' and isinstance(operand2, Vec):
        return operand + operand2

    elif isinstance(operand, Vec) and op == '-' and isinstance(operand2, Vec):
        return operand - operand2

    elif isinstance(operand, Vec) and op == '*' and isinstance(operand2, Vec):
        return operand * operand2

    elif isinstance(operand, Vec) and op == '*' and isinstance(operand2, int):
        return operand * operand2

    elif isinstance(operand, Matrix) and op == '+' and isinstance(operand2, Matrix):
        return operand + operand2

    elif isinstance(operand, Matrix) and op == '-' and isinstance(operand2, Matrix):
        return operand - operand2

    elif isinstance(operand, Matrix) and op == '*' and isinstance(operand2, int):
        return operand * operand2

    elif isinstance(operand, Matrix) and op == '*' and isinstance(operand2, Matrix):
        return operand + operand2

    else:
        raise ValueError("{} is not type Vec or type Matrix.".format(operand))

if I write my view like this everything works as expected minus the computation I want to make.

@api_view(['POST'])
def compute_linear_algebra_expression(request):
    """
    Given a Linear Algebra expression this view evaluates it.

    @param request: Http POST request
    @return: linear algbera expression
    """
    serializer = LinearAlgebraSerializer(data=request.data)
    
    if serializer.is_valid():
        serializer.save()
        return Response(serialized.data, status=status.HTTP_201_CREATED)

    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Solution

  • So, after some investigation I was able to solve it.

    I added the following code and I was able to see how the data looked like:

    def evaluate(exp):
        """
        Evaluate a Linea Algebra expression.
        """
        if isinstance(exp, tuple):
            if len(exp) == 3:
                operand, op, operand2 = exp
            else:
                raise ValueError("tuple {} is not of size 3.".format(exp))
        else:
            raise ValueError("{} in not a tuple.".format(exp))
                             
        if isinstance(operand, Vec) and op == '+' and isinstance(operand2, Vec):
            return operand + operand2
        ...
    

    in my view (see above) I have this:

    
    if serializer.is_valid():
            serializer.save()
            data = serializer.data
            algebra_expr = data['expression']
            algebra_expr = tuple(algebra_expr)
    
    

    well it turns out that tuple was dividing the input into characters separated by commas; hence the error.

    so I solved it by:

    if serializer.is_valid():
            serializer.save()
            data = serializer.data
            algebra_expr = data['expression']
            algebra_expr = eval(algebra_expr)
            algebra_expr = evaluate(algebra_expr)
    
    

    notice the eval call. that solved it.