在序列化程序 django rest 框架中使用非主键验证外键字段

时间:2021-06-18 11:53:10

标签: python django serialization django-rest-framework django-serializer

我正在使用 Django Rest 框架来创建 API。我有以下型号:

class Currency(models.Model):
    name = models.CharField(max_length=15)
    code = models.CharField(max_length=5)
    exchange_rate = models.DecimalField(max_digits=5, decimal_places=4)

这里是 API 请求的序列化程序-

class WalletCreditSerializer(serializers.Serializer):
    wallet = serializers.PrimaryKeyRelatedField(queryset=Wallet.objects.all())
    amount = serializers.DecimalField(max_digits=10, decimal_places=4)
    currency = serializers.PrimaryKeyRelatedField(queryset=Currency.objects.all())
    message = serializers.CharField(max_length=150, allow_null=True)

当我在请求中传递货币 ID 时,序列化程序运行良好

{
    "wallet": 1,
    "amount": 23,
    "currency": 1,
    "message": "Test message"
}

但要求是通过货币代码

{
    "wallet": 1,
    "amount": 23,
    "currency": "USD",
    "message": "Test message"
}

实现这一目标的最佳方法是什么?有人能举个例子吗?

2 个答案:

答案 0 :(得分:0)

您可以通过使用“PrimaryKeyRelatedField”中的“pk_field”参数来实现这一点

currency=serializers.PrimaryKeyRelatedField(queryset=Currencies.objects.all(), pk_field='code')

或者通过使用“CharField”和这样的验证:

class WalletCreditSerializer(serializers.Serializer):
    wallet = serializers.PrimaryKeyRelatedField(queryset=Wallet.objects.all())
    amount = serializers.DecimalField(max_digits=10, decimal_places=4)
    currency = serializers.CharField(max_length=150, allow_null=False)
    message = serializers.CharField(max_length=150, allow_null=True)

    def validate_currency(value):
        currency = Currencies.objects.filter(code=value).first()
        if not currency:
            raise ValidationError("error message here")
        returnt currency

答案 1 :(得分:0)

您可以将序列化程序的字段 currency 更改为 CharField 并在序列化程序中添加一个 create 方法,该方法将获取字符串的实际对象USD 在字段 currency 中提供。

class WalletCreditSerializer(serializers.Serializer):
        wallet = serializers.PrimaryKeyRelatedField(queryset=Wallet.objects.all())
        amount = serializers.DecimalField(max_digits=10, decimal_places=4)
        currency = serializers.CharField(max_length=150, allow_null=False)
        message = serializers.CharField(max_length=150, allow_null=True)
    
    def create(self, validated_data):
        try:
            validated_data['currency'] = Currencies.objects.get(code=validated_data['currency'])
        except Currencies.DoesNotExist:
            raise serializers.ValidationError('Please provide the valid option for currency')

        return Model.objects.create(**validated_data) #remember to replace 'Model' with your actual model name.

此外,在您的 models.py 中,您已经创建了名为 Currency 的模型,并且在您使用的字段 currency 的序列化程序中相关模型名称为 Currencies。我不确定这些模型中的哪一个会保留字符串 USD 的对象。