Search code examples
pythondjangoserializationdjango-rest-frameworkdjango-serializer

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


I'm using the Django Rest framework to create an API. I have the following models:

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)

and here is the serializer for the API request-

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)

The serializer works well when I am passing currency id in request

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

But the requirement is the pass the Currency code

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

What is the best way to achieve this? Could someone provide an example?


Solution

  • You can achieve this by using 'pk_field' param from 'PrimaryKeyRelatedField'

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

    or by using 'CharField' and validation like this:

    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