JSON 字段有时包含字符串,有时包含对象
JSON field sometimes contains string, sometimes object
我正在使用 Django 休息框架来验证从接收金融交易的 API 收到的 JSON。序列化程序已经工作了几年了。 JSON 中的商家字段将始终包含商家作为带有商家 ID、名称等的嵌套对象。但现在我有时只收到商家 ID 作为字符串并且 JSON 现在无法验证.
如何设置我的序列化程序以允许商家字段中的字符串或对象?
基本上商户字段需要接受以下任一:
merchant = MerchantSerializer(required=False, allow_null=True)
merchant = serializers.CharField(required=False, max_length=50)
serializers.py
class MerchantSerializer(serializers.Serializer):
id = serializers.CharField(required=True, max_length=50)
name = serializers.CharField(required=True, max_length=100)
atm = serializers.BooleanField(required=False, allow_null=True)
address = AddressSerializer(required=False, allow_null=True)
logo = serializers.URLField(required=False, allow_null=True, max_length=500, min_length=None, allow_blank=True)
class DataSerializer(serializers.Serializer):
account_id = serializers.CharField(required=True, max_length=50)
amount = serializers.IntegerField(required=True)
created = serializers.DateTimeField()
currency = serializers.CharField(required=True, max_length=3)
description = serializers.CharField(required=True, max_length=250)
id = serializers.CharField(required=True, max_length=50)
category = serializers.CharField(required=True, max_length=100)
decline_reason = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=100)
merchant = MerchantSerializer(required=False, allow_null=True)
counterparty = CounterpartySerializer(required=False, allow_null=True)
metadata = MetadataSerializer(required=False, allow_null=True)
您需要将 name
字段的 required
设置为 false。
class MerchantSerializer(serializers.Serializer):
id = serializers.CharField(required=True, max_length=50)
name = serializers.CharField(required=False, max_length=100) # this field
atm = serializers.BooleanField(required=False, allow_null=True)
address = AddressSerializer(required=False, allow_null=True)
logo = serializers.URLField(required=False, allow_null=True, max_length=500, min_length=None, allow_blank=True)
希望对您有所帮助。
您可以重写 to_internal_value
,这样它会尝试解析传递的数据。在下面的解决方案中,它只是检查数据是否是字典,如果不是,则将其设置为字典。
此解决方案将允许序列化程序接受一个字符串,但在序列化程序中它将变成一个仅包含键 id
的字典。
class MerchantSerializer(serializers.Serializer):
id = serializers.CharField(required=True, max_length=50)
# other fields ...
def to_internal_value(self, data):
parsed_data = data
if not isinstnace(parsed_data, dict):
parsed_data = { "id": data }
return super().to_internal_value(parsed_data)
尽管如此,您可能必须更改序列化程序的一些验证以允许它仅接收 id
。
我正在使用 Django 休息框架来验证从接收金融交易的 API 收到的 JSON。序列化程序已经工作了几年了。 JSON 中的商家字段将始终包含商家作为带有商家 ID、名称等的嵌套对象。但现在我有时只收到商家 ID 作为字符串并且 JSON 现在无法验证.
如何设置我的序列化程序以允许商家字段中的字符串或对象?
基本上商户字段需要接受以下任一:
merchant = MerchantSerializer(required=False, allow_null=True)
merchant = serializers.CharField(required=False, max_length=50)
serializers.py
class MerchantSerializer(serializers.Serializer):
id = serializers.CharField(required=True, max_length=50)
name = serializers.CharField(required=True, max_length=100)
atm = serializers.BooleanField(required=False, allow_null=True)
address = AddressSerializer(required=False, allow_null=True)
logo = serializers.URLField(required=False, allow_null=True, max_length=500, min_length=None, allow_blank=True)
class DataSerializer(serializers.Serializer):
account_id = serializers.CharField(required=True, max_length=50)
amount = serializers.IntegerField(required=True)
created = serializers.DateTimeField()
currency = serializers.CharField(required=True, max_length=3)
description = serializers.CharField(required=True, max_length=250)
id = serializers.CharField(required=True, max_length=50)
category = serializers.CharField(required=True, max_length=100)
decline_reason = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=100)
merchant = MerchantSerializer(required=False, allow_null=True)
counterparty = CounterpartySerializer(required=False, allow_null=True)
metadata = MetadataSerializer(required=False, allow_null=True)
您需要将 name
字段的 required
设置为 false。
class MerchantSerializer(serializers.Serializer):
id = serializers.CharField(required=True, max_length=50)
name = serializers.CharField(required=False, max_length=100) # this field
atm = serializers.BooleanField(required=False, allow_null=True)
address = AddressSerializer(required=False, allow_null=True)
logo = serializers.URLField(required=False, allow_null=True, max_length=500, min_length=None, allow_blank=True)
希望对您有所帮助。
您可以重写 to_internal_value
,这样它会尝试解析传递的数据。在下面的解决方案中,它只是检查数据是否是字典,如果不是,则将其设置为字典。
此解决方案将允许序列化程序接受一个字符串,但在序列化程序中它将变成一个仅包含键 id
的字典。
class MerchantSerializer(serializers.Serializer):
id = serializers.CharField(required=True, max_length=50)
# other fields ...
def to_internal_value(self, data):
parsed_data = data
if not isinstnace(parsed_data, dict):
parsed_data = { "id": data }
return super().to_internal_value(parsed_data)
尽管如此,您可能必须更改序列化程序的一些验证以允许它仅接收 id
。