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

Validating a foreign key field with non-Primary Key in a serializer django rest framework

我正在使用 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"
}

实现此目标的最佳方法是什么?有人可以举个例子吗?

您可以使用 '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

您可以将序列化程序的字段 currency 更改为 CharField 并在序列化程序中添加一个创建方法,该方法将获取字符串 [=24= 的实际对象]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.

的对象