The DECIMAL type field fetch data become string

Question:

In my table:

My discount type is DECIMAL:

Enter image description here

My data in table:

Enter image description here

But why when I fetch data in API, there gets string?

enter image description here

I use Django and Django REST framework as the backend.


belong_product: "server"
ctime: "2018-04-11T15:41:15.744959+08:00"
desc: ""
discount: "0.005"
id: 1
is_enable: false
max_count: 5
min_count: 0
name: "one"
uptime: "2018-04-11T15:41:15.745226+08:00"

My ListAPI view:

class DiscountItemByUserOwnCountListAPIView(ListAPIView):
    serializer_class = DiscountItemByUserOwnCountSerializer
    permission_classes = [IsSuperAdmin]
    pagination_class = CommonPagination
    def get_queryset(self):
        return DiscountItemByUserOwnCount.objects.all()

My model:

class DiscountItemByUserOwnCount(models.Model):
    name = models.CharField(max_length=16, help_text="name")
    desc = models.CharField(max_length=512, null=True, blank=True, help_text="desc")
    min_count = models.IntegerField(help_text="min")
    max_count = models.IntegerField(help_text="max")   
    discount = models.DecimalField(max_digits=4, decimal_places=3, default=0.000, unique=True,
                                   help_text="point")  
    belong_product = models.CharField(max_length=16, help_text="belongDISCOUNT_PRODUCT_TYPE")

    is_enable = models.BooleanField(default=False)

    ctime = models.DateTimeField(auto_now_add=True)
    uptime = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name
    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['min_count', '-id']
Asked By: user7693832

||

Answers:

The default decimal representation in Django REST framework is string. To disable this behavior, add following to your settings.py file:

REST_FRAMEWORK = {
    'COERCE_DECIMAL_TO_STRING': False,
    # Your other settings
    ...
}

See details in the documentation.

Answered By: neverwalkaloner

It is a string because otherwise you’ll get rounding errors. This can be easily seen using a Python shell:

>>> import decimal
>>> from decimal import Decimal
>>> Decimal(0.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
>>> Decimal('0.3')
Decimal('0.3')
>>> 

Also note that JSON doesn’t have decimal. Only integers and floats.

Answered By: Linovia

The default behaviour of the Decimal field is string in REST_FRAMEWORK to override for the whole app we can use

REST_FRAMEWORK = {
    'COERCE_DECIMAL_TO_STRING': False,
    # Your other settings
    ...
}

but if You want to override it for one field You can do as following

field = serializers.DecimalField(coerce_to_string=False)

by default coerce_to_string is True.
checkout this out

Answered By: fire_demesne