Django остальные рамки несколько полей в одно - PullRequest
1 голос
/ 04 октября 2019
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.'
                }
            }
        })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...