class Wall(BaseComponent):
studs_material = models.CharField(max_length=255, null=True, blank=True)
studs_spacing = models.FloatField(null=True, blank=True)
studs_size = models.CharField(max_length=255, null=True, blank=True)
У меня есть модель, которая должна представлять сглаженные данные из разных источников. Для проверки данных из этих источников я использую сериализаторы DRF. Я столкнулся с вопросом, как сгруппировать поля 3 в одно в методе representation
.
Данные приходят ко мне в следующем формате:
{
`studs`: 'Steel, 2x4, 16'
}
Я использую сериализатор модели и использую source='*'
для заполнения данных
class FoundationWallSerializer(serializers.ModelSerializer):
studs = StudTypeSerializer(source='*', required=False)
class Meta:
model = Wall
fields = ('studs',)
в дочернем сериализаторе я делаю следующее:
class StudTypeSerializer(serializers.Serializer):
"""
StudType objects are serialized into 'Steel, 2x4, 16" o.c.' notation.
"""
MATERIAL_CHOICES = (
('Steel', 'steel'),
)
size = serializers.CharField(
source='studs_size',
label='Type of stud, joist, etc. (2x4, 2x6, etc)')
spacing = serializers.FloatField(
source='studs_spacing')
material = SimulationMappingField(source='studs_material', choices=MATERIAL_CHOICES)
def create(self, validated_data):
raise NotImplementedError
def update(self, instance, validated_data):
raise NotImplementedError
def to_representation(self, instance):
try:
material = instance.pop('material')
size = instance.pop('size')
spacing = instance.pop('spacing')
except KeyError:
return 'None'
return f'{material}, {size}, {spacing}\'\' o.c.'
def to_internal_value(self, data):
if data == 'None':
return {}
material, size, spacing = [col.strip() for col in data.split(',')]
return {
'material': material,
'size': size,
'spacing': spacing
}
Проблема, когда я делаю так для импорта данных:
def test_import(self):
obj = Wall(
component_library=self.library)
obj.save()
data = {
'foundationwall': {
'foundationwallType': {
'studtype': 'Steel, 2x4, 16" o.c.'
}
}
}
serializer = FoundationWallSerializer(instance=obj, data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
self.assertEqual(json.loads(json.dumps(serializer.data)), data)
instance
в to_representation
метод не имеет material
spacing
и size
, и я получил: - {'foundationwall': {'foundationwallType': {'studtype': 'None'}}}
Код для экспорта отлично работает
def test_export(self):
obj = Wall(
component_library=self.library,
system_identifier='test-wall',
same_as=None,
area=1,
studs_spacing='16',
studs_size='2x4',
studs_material='steel')
obj.save()
serializer = FoundationWallSerializer(instance=obj)
xml = xmltodict.unparse(serializer.data)
self.assertEqual(json.loads(json.dumps(serializer.data)), {
'foundationwall': {
'foundationwallType': {
'studtype': 'Steel, 2x4, 16" o.c.'
}
}
})