验证不适用于 SerializerMethodField

问题描述 投票:0回答:3

我正在开发 Django DRF 应用程序。我有两个型号

Organization
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,
    )
    ...

我想验证组织数据

组织必须至少拥有一个 is_main=True 的帐户

但我的验证不起作用(看起来没有

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)")

示例:对于此数据,我预计验证错误:(只有一个 acc 带有“is_main”: false,)

"accounts": [
            {
                "id": 1,
                "is_main": false,
                "bank_name": "Sber",
                "bank_bik": "123",
                "bank_account": "123",
                "correspondent_account": "312",
                "organization": 3
            },
]
python django django-rest-framework
3个回答
1
投票

如文档中所述 https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

验证不适用于方法字段,因为方法字段是只读字段。


0
投票

我的解决方案

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)")

0
投票

我能够通过覆盖序列化器的

to_representation
来修复它,如下所示:

class OrganizationSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Organization
        fields = '__all__'
        read_only_fields = ("id",)
    
    def to_representation(self, instance):
        data = super().to_representation(instance)
        accounts = None
        if instance.accounts is not None:
            accounts = BankAccountSerializer(obj.accounts, many=True).data
        data['accounts'] = accounts
        return data 
© www.soinside.com 2019 - 2024. All rights reserved.