Я использую MongoDB, соединение обеспечивается Djongo, поверх используется DRF для управления всеми запросами к mi API.
Мои данные (профиль) структурированы следующим образом
{
"name" : "profile name",
"description" : "this is a description",
"params" : "X1, X2,X3, etc",
"config" : "CONFIG OF DEVICE",
"user" : {
"name" : "user name",
"middle_name" : "test middle name",
"last_name" : "test last name",
"email" : "test@test.com",
"institute" : {
"name" : "MIT",
"place" : {
"coordinates" : [ 30.0, 101.0, 0.0 ],
"type" : "Point"
},
"country" : "US"
}
},
"place" : {
"coordinates" : [ 90.0, 901.0, 10.0 ],
"type" : "Point"
},
"devices" : [
{
"name" : "DEVICE 1",
"verification_code" : "",
"verificated" : 0,
"configuration" : "kjk",
"places" : [
{
"coordinates" : [ 30.0, 101.0, 0.0 ],
"type" : "Point"
},
{
"coordinates" : [ 31.0, 102.0, 1.0 ],
"type" : "Point"
}
]
}
]
}
Я знаю, что координаты неверны, но это просто для проверки.
Хорошо, я отправляю этот объект на мой взгляд, а затем в ProfileSerializer, это отвечает за проверку встроенных объектов (у каждого есть свойсобственный сериализатор).После проверки данных информация сохраняется без проблем, как вы можете видеть на следующем рисунке:
Но проблема в том, когда я пытаюсь.восстановить все профили.Просто координаты равны нулю. Другие встроенные объекты извлекаются надлежащим образом, только объект Place искажен.Далее я покажу вам ответ:
[
{
"id": 22,
"name": "profile name",
"description": "this is a description",
"params": "X1, X2,X3, etc",
"config": "CONFIG OF DEVICE",
"user": {
"name": "user name",
"middle_name": "test middle name",
"last_name": "test last name",
"email": "test@test.com",
"institute": {
"name": "MIT",
"place": {
"coordinates": **null**,
"type": "Point"
},
"country": "US",
"created_at": "2019-03-21T20:43:33.928000Z"
},
"created_at": "2019-03-21T20:43:33.959000Z"
},
"place": {
"coordinates": **null**,
"type": "Point"
},
"devices": [
{
"name": "DEVICE 1",
"verificated": 0,
"configuration": "kjk",
"places": [
{
"coordinates": **null**,
"type": "Point"
},
{
"coordinates": **null**,
"type": "Point"
}
],
"created_at": "2019-03-21T20:43:33.898000Z"
}
],
"created_at": "2019-03-21T20:43:33.976000Z"
}
]
Только для этих вопросов я опишу / покажу сериализатор одного объекта, но если вам понадобится некоторая информация, я получу вас как можно скорее.
Модели
class Place(models.Model):
coordinates = models.ListField(blank=True, null=True, default=[0.0, 0.0, 0.0])
type = models.CharField(max_length=10, default="Point")
objects = models.DjongoManager()
class Profile(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(default="Without Description")
params = models.TextField(default="No params")
config = models.CharField(max_length=200)
user = models.EmbeddedModelField(
model_container=User
)
place = models.EmbeddedModelField(
model_container=Place
)
devices = models.ArrayModelField(
model_container=Device
)
created_at = models.DateTimeField(auto_now_add=True)
objects = models.DjongoManager()
Сериализаторы
class PlaceSerializer(serializers.ModelSerializer):
coordinates = serializers.ListSerializer(
child=serializers.FloatField(),
)
class Meta:
model = Place
fields = ('id', 'coordinates', 'type')
class ProfileSerializer(serializers.ModelSerializer):
user = UserSerializer( )
place = PlaceSerializer()
devices = DeviceSerializer( many=True)
class Meta:
model = Profile
fields = ('id', 'name', 'description', 'params', 'config',
'user', 'place', 'devices', 'created_at')
depth=8
def create(self, validated_data):
# get principal fields
user_data = validated_data.pop('user')
**place_data = validated_data.pop('place')**
devices_data = validated_data.pop('devices')
# get nested fields
# devices nested fields
devices = []
for device in devices_data:
places = []
places_data = device.pop('places')
for place in places_data:
places.append( **Place(coordinates=place['coordinates'], type=place['type'])** )
device['places'] = places
devices.append( Device.objects.create(**device) )
validated_data['devices'] = devices
# user nested fields
institute_data = user_data.pop('institute')
place = institute_data.pop('place')
institute_data['place'] = Place(coordinates=place['coordinates'], type=place['type'])
user_data['institute'] = Institute.objects.create(**institute_data)
validated_data['user'] = User.objects.create(**user_data)
profile = Profile.objects.create(**validated_data)
return profile
Я определил PlaceSerializer по-разному, но все они получают один и тот же результат, Ниже опишите эти способы
CASE 1
class PlaceSerializer(serializers.ModelSerializer):
coordinates = serializers.ListSerializer(
child=serializers.FloatField(),
)
CASE 2
class CoordinatesSerializer(serializers.ListSerializer):
child=serializers.FloatField()
class PlaceSerializer(serializers.ModelSerializer):
coordinates = CoordinatesSerializer()
CASE 3
class PlaceSerializer(serializers.ModelSerializer):
coordinates = serializers.ListField(
child=serializers.FloatField()
)
CASE 4
class PlaceSerializer(serializers.ModelSerializer):
coordinates = serializers.ListField()
CASE 5
class PlaceSerializer(serializers.ModelSerializer):
coordinates = serializers.ListSerializer()
#gives error for child is not present
Я изменил типы, CharField, IntegerField, FloatField и т. Д. С теми же результатами.
Еще один тест, который я сделал, - добавление в сериализатор методов create, update, to_representation, to_internal_value, все это для лучшего управления информацией, которая будет сохранена, извлечена, но все работает.Еще одно любопытство, если я добавлю простое поле списка, например [10,90,1], в отличие от этого, если поле ListField находится внутри Place Objects,
будет сохранено и извлечено без проблем. Пожалуйста, если вы знаете, как решить эту проблему, ярад тебе.