I have some problem with handling nested serializers (DRF).
I want to collect data with some structure like this:
{
'some_tekst': 'test_text',
'measurements': [
{'int_test': 1, 'char_test': '1'},
{'int_test': 2, 'char_test': '2'}
]
}
I'm using the documentation (https://www.django-rest-framework.org/api-guide/serializers/#dealing-with-nested-objects) and i'm looking at (https://medium.com/@raaj.akshar/creating-reverse-related-objects-with-django-rest-framework-b1952ddff1c) and still have the HTTP 400 response:
'{"measurements":["This field is required."]}'
models.py
class Data(models.Model):
datetime = models.CharField(max_length=100)
def __str__(self):
return 'just testing'
class Measurement(models.Model):
# EDIT:
# data = models.ForeignKey(Data, on_delete=models.CASCADE) #deleted
char_test = models.CharField(max_length=100)
test = models.IntegerField(default=0)
def __str__(self):
return self.char_test
serializers.py:
class MeasurementSerializer(serializers.ModelSerializer):
class Meta:
model = Measurement
fields = '__all__'
class DataSerializer(serializers.ModelSerializer):
# EDIT:
#measurements = MeasurementSerializer(many=True)
measurements = MeasurementSerializer(many=True, source='measurement_set')
class Meta:
model = Data
fields = ['datetime', 'measurements']
# EDIT:
#def create(self, validated_data):
# measurement_validated_data = validated_data.pop('measurements')
# data = Data.objects.create(**validated_data)
# Measurement.objects.create(data=data, **measurement_validated_data)
# return data
def create(self, validated_data):
measurement_validated_data = validated_data.pop('measurements')
data = Data.objects.create(**validated_data)
for measurement_data in measurement_validated_data:
Measurement.objects.create(data=data, **measurement_data)
return data
views.py
class DataViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
serializer_class = DataSerializer
queryset = Data.objects.all()
class MeasurementViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
serializer_class = MeasurementSerializer
queryset = Measurement.objects.all()
And my simple post request:
data = {
"datetime": "testdatatime",
"measurements": [
{'test': 1, 'char_test': '1'},
{'test': 2, 'char_test': '2'},
],
}
r = requests.post(
'http://127.0.0.1:8000/api/data/',
data=data,
)
Did I forget something?
Edit: There is API endpoint from DRF:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"name": "Data List",
"description": "API endpoint that allows groups to be viewed or edited.",
"renders": [
"application/json",
"text/html"
],
"parses": [
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data"
],
"actions": {
"POST": {
"datetime": {
"type": "string",
"required": true,
"read_only": false,
"label": "Datetime",
"max_length": 200
},
"measurements": {
"type": "field",
"required": true,
"read_only": false,
"label": "Measurements",
"child": {
"type": "nested object",
"required": true,
"read_only": false,
"children": {
"id": {
"type": "integer",
"required": false,
"read_only": true,
"label": "ID"
},
"char_test": {
"type": "string",
"required": true,
"read_only": false,
"label": "Char test",
"max_length": 100
},
"test": {
"type": "integer",
"required": false,
"read_only": false,
"label": "Test",
"min_value": -2147483648,
"max_value": 2147483647
}
}
}
}
}
}
}
Edit 2: Error on the django side (console)
django_web | Bad Request: /api/data/
django_web | [31/Mar/2020 22:54:39] "POST /api/data/ HTTP/1.1" 400 44