Django object of type fraction is not json serializable

75 Views Asked by At
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from math import sqrt
from fractions import Fraction




def index(request):
    return render(request, 'home/index.html', {})

def multiplication(request):
    return render(request, 'multiplication/multiplication.html', {})


def compute(request):
    a = int(request.POST.get("a"))
    b = int(request.POST.get("b"))
    c = int(request.POST.get("c"))
    det = b*b-4*a*c
    rdet = sqrt(det)
    x1= (-b-rdet)/(2*a)
    x2= (-b+rdet)/(2*a)
    x3= Fraction(15, 45)
    return JsonResponse({"op_result": det, "op_result2": x1, "op_result3": x2, "op_result4": 2*a, "op_result5": -b, "op_result6": c,"op_result7": x3})

in my view.py, I tried to send back to my html, the results of the function fractions through the var x3

x3= Fraction(15, 45) and sent the result with JsonResponse. But I have an error message :

object of type fraction is not json serializable

I do not understand where is the mistake.

Thank you for your help

2

There are 2 best solutions below

5
Dhruv Patel On

you cannot serialize a fraction but can make a custom serializer and pass numerator and denominator in that

from django.http import JsonResponse
from django.views import View
from fractions import Fraction
import json

class FractionEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Fraction):
            return {"numerator": obj.numerator, "denominator": obj.denominator}
        return super().default(obj)

class generate_dummy_energy_usage(View):
    def get(self,request):
        a = 10
        b = 40
        c = 30
        det = b*b-4*a*c
        rdet = sqrt(det)
        x1 = (-b-rdet)/(2*a)
        x2 = (-b+rdet)/(2*a)
        x3 = Fraction(15, 45)
        return JsonResponse({"op_result": det, "op_result2": x1, "op_result3": x2, "op_result4": 2*a, "op_result5": -b, "op_result6": c, "op_result7": x3}, encoder=FractionEncoder)

this is output in jsonresponse
[![enter image description here][1]][1]

rather than sending as fraction just compute it and send it as string would be a easier approach

response

0
jean-michel ligner On
document.querySelector("#fetch-call").addEventListener("click", event => {
    event.preventDefault();

    let form = new FormData();

    form.append("a", document.querySelector("#a").value);
    form.append("b", document.querySelector("#b").value);
    form.append("c", document.querySelector("#c").value);

    let csrfTokenValue = document.querySelector('[name=csrfmiddlewaretoken]').value;
    let request = new Request("{% url 'compute' %}", {method: 'POST',
                                                      body: form,
                                                      headers: {"X-CSRFToken": csrfTokenValue}})
    fetch(request)
        .then(response => response.json())
        .then(result => {
            let resultParagraph = document.querySelector("#operation");
            resultParagraph.innerHTML ="Le discriminant "+"\\(\\Delta\\)"+" =" + result["op_result"] ;
            MathJax.typeset();

            let resultParagraph2 = document.querySelector("#operation2");
            resultParagraph2.innerHTML ="La solution x1 est :"+"\\("+result["op_result5"]+"-"+"\\sqrt"+result["op_result"]+"\\over"+result["op_result4"]+"\\)"+" et la solution x2 est :"+"\\("+result["op_result5"]+"+"+"\\sqrt"+result["op_result"]+"\\over"+result["op_result4"]+"\\)";
            MathJax.typeset();
            
            let resultParagraph3 = document.querySelector("#operation3");
            resultParagraph3.innerHTML ="la valeur approchée de x1 est: " + result["op_result2"] + " et x2 est : "+ result["op_result3"];
            
            let resultParagraph4 = document.querySelector("#operation4");
            resultParagraph4.innerHTML ="facration " + result["op_result7"];
            
                   })
})