在Django Rest Framework中将JSON的整数列表转换为String

时间:2017-01-04 11:35:15

标签: python json django rest django-rest-framework

我试图从用户获取整数列表,并在Django Rest Framework中保存模型之前将它们转换为逗号分隔字符串。

我的模型是这样的:

class Message(models.Model):
    name = models.CharField(max_length=100)
    regions = models.TextField(validators=[RegexValidator(regex='^[0-9,]+$')])
    created_at = models.DateTimeField(auto_now_add=True)

和我的Serializer:

class MessageSerializer(ModelSerializer):
    regions_list = serializers.ListField(child=serializers.IntegerField())

    class Meta:
        model = Message
        fields = ('id', 'name', 'regions_list', 'created_at')
        read_only_fields = ('created_at')

我的意见:

{
  "name": "TEST",
  "regions_list": [1, 2, 3, 4]
}

如何在db?

中将regions_list转换为逗号分隔的字符串(区域)

Django :1.10
DRF :3.5

3 个答案:

答案 0 :(得分:4)

您可以在create中覆盖MessageSerializer方法:

class MessageSerializer(ModelSerializer):
    # .... 

    def create(self, validated_data):
        regions_string = ','.join(validated_data.pop('regions_list', []))
        validated_data['regions'] = regions_string
        return Message.objects.create(**validated_data)

答案 1 :(得分:3)

如果您使用的是PostgresSQL数据库,则可以使用内置ArrayField的Django。这将允许您在IntegerField上使用基于Django的标准字段属性。例如,您可以将允许的整数范围限制为可用区域(即1-8)。

class Message(models.Model):
  # ...
  regions = ArrayField(models.IntegerField(min_value=1, max_value=8), default=list)

如果未包含参数,default=list语句会在数据库中创建一个空列表。

答案 2 :(得分:3)

我覆盖了to_representationto_internal_value方法。它对我有用。

class MessageSerializer(ModelSerializer):
    regions_list = serializers.ListField(child=serializers.IntegerField())

    class Meta:
        model = Message
        fields = ('id', 'name', 'regions_list', 'created_at')
        read_only_fields = ('created_at')

    def to_representation(self, instance: Message):
        instance.regions_list = [int(i) for i in instance.regions.split(',')]
        return super(MessageSerializer, self).to_representation(instance)

    def to_internal_value(self, data):
        ret = super(MessageSerializer, self).to_internal_value(data)
        if ret['regions_list']:
            ret['regions'] = ','.join(str(i) for i in ret['regions_list'])

        return ret