Home > OS >  Validation isn't working for SerializerMethodField
Validation isn't working for SerializerMethodField

Time:06-09

I am working on my Django DRF app. I have two models Organization and BankAccount

class Organization(models.Model):
    ...

class BankAccount(models.Model):
    is_main = models.BooleanField(default=False) # organization should have 1 main account
    organization = models.ForeignKey(
        Organization,
        related_name="accounts",
        on_delete=models.CASCADE,
    )
    ...

I want to validate Organization data

Organization must have at least one account with is_main=True

but my validation isn't working (it looks like there are no validate_accounts cals.

class OrganizationSerializer(serializers.ModelSerializer):
    accounts = serializers.SerializerMethodField()
    
    class Meta:
        model = Organization
        fields = '__all__'
        read_only_fields = ("id",)
    
    def get_accounts(self, obj):
        if obj.accounts is not None:
            return BankAccountSerializer(obj.accounts, many=True).data
        return None
    
    def validate_accounts(self, value):
        """
        Organization should have account with 'is_main' true
        """
        raise ValueError(value) # Don't see exception in logs
        if not value:
            return value
        
        for account in value: # check all accounts
            if account["is_main"] == True:
                return value
        raise serializers.ValidationError("Organization should have main account  (is_main=true)")

Example: For this data I expect validation error: (only one acc with "is_main": false,)

"accounts": [
            {
                "id": 1,
                "is_main": false,
                "bank_name": "Sber",
                "bank_bik": "123",
                "bank_account": "123",
                "correspondent_account": "312",
                "organization": 3
            },
]

CodePudding user response:

as described in documentation https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

validation is not working on methodfield because methodfield is read-only field.

CodePudding user response:

My solution

def get_accounts(self, obj):
    if obj.accounts is not None:
        return self.validate_accounts(
            BankAccountSerializer(obj.accounts, many=True).data
        )
    return None

def validate_accounts(self, value):
    """
    Organization should have account with 'is_main' true
    """
    if not value:
        return value
    
    for account in value: # caheck all accounts
        if account["is_main"] == True:
            return value
    raise serializers.ValidationError("Organization should have main account  (is_main=true)")
  • Related