Reputation: 4984
How to serialize list of list of Floats using Django Rest serializers?
My data is (repr
of my list of object):
[{
'id': '413',
'data': [
[None, 32.33125, None, None],
[None, 37.96, 48.70112359550562, 66.118],
[None, None, 58.06576923076923, 77.31023809523809],
[None, None, None, 110.0075],
[None, None, None, 139.89]
]
}, {
'id': '406',
'data': [
[None, 35.33125, None, None],
[None, 37.96, 43.123, 66.118],
[None, None, 58.12, 72,123],
[None, None, None, 119.000234],
[None, None, None, 139.89]
]
}]
For users trying to propose different approach, I need to explain that I need serializer class because I want to use generics.ListAPIView
and I need to setup serializer_class
property.
Upvotes: 2
Views: 10253
Reputation: 10256
You can use the biult-in json
module.
data = [{
'id': '413',
'data': [
[None, 32.33125, None, None],
[None, 37.96, 48.70112359550562, 66.118],
[None, None, 58.06576923076923, 77.31023809523809],
[None, None, None, 110.0075],
[None, None, None, 139.89]
]
}, {
'id': '406',
'data': [
[None, 35.33125, None, None],
[None, 37.96, 43.123, 66.118],
[None, None, 58.12, 72,123],
[None, None, None, 119.000234],
[None, None, None, 139.89]
]
}]
import json
json_data = json.dumps(data)
You can mix this with a DRF view:
from rest_framework.response import Response
...
json_data = json.dumps(data)
return Response(json_data)
EDIT
To use ListAPIView
assuming your data are coming from a model named Mymodel
# Serializer
from rest_framework import serializers
class MymodelSerializer(serializers.ModelSerializer):
class Meta:
model = Mymodel
# View
from rest_framework import generics
class MymodelList(generics.ListAPIView):
queryset = Mymodel.objects.filter(whatever=whatever)
def list(self, request):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
Upvotes: 1
Reputation: 4984
You must create Field
class that will work with Null
values:
class FixedFloatField(serializers.FloatField):
def to_internal_value(self, data):
if data is None:
return data
return super().to_internal_value(data)
def to_representation(self, value):
if value is None:
return value
return super().to_representation(value)
(because standard one throws TypeError: float() argument must be a string or a number, not 'NoneType'
)
Now use this Serializer (the trick is to use ListField
):
class SearchResultSerializer(serializers.Serializer):
id = serializers.IntegerField()
data = serializers.ListField(
child=serializers.ListField(
child=FixedFloatField(
allow_null=True,
required=False,
default=None
)
)
)
Upvotes: 8