簡體   English   中英

Django Rest Framework - 有條件地使序列化器的字段需要或不使用其他字段值

[英]Django Rest Framework - conditionally make serializer's field required or not using other field value

在我的 DRF 項目中,我有一個模型:

class Item(BaseModel):
    PRIVATE = 'PRIVATE'
    COMPANY = 'COMPANY'
    ACCOUNT_TYPES = (
        (PRIVATE, _('Private')),
        (COMPANY, _('Company')),
    )
    company_name = models.CharField(max_length=128, null=True, blank=True)
    person_name = models.CharField(max_length=128, null=True, blank=True)
    account_type = models.CharField(max_length=32, choices=ACCOUNT_TYPES)
    phone = models.CharField(max_length=128, null=True, blank=True)
    email = models.EmailField(max_length=128, null=True, blank=True)

和序列化程序中的 ItemSerializer ,例如:

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('account_type', 'company_name', 'person_name')

    def create(self, validated_data):
        print('ItemSerializer, create')
        print('validated_data:', validated_data)
        return super().create(validated_data)

    def validate(self, attrs):
        print('ItemSerializer validate, attrs:', attrs)
        return attrs

正如您在模型中看到的,有字段company_nameperson_name ,模型中不需要它們。

要創建項目,必須指定account_type 它是PRIVATECOMPANY

現在,在我的序列化程序中,如果帳戶類型是公司或私人,我想使特定字段成為必需。 例如, account_type 是COMPANY ,我想使字段company_name必需。 如果 account_type 是PRIVATE我想讓person_name必需。

  1. 哪種方法是實現這一目標的合適空間,我該如何做到這一點?
  2. 同樣使用上述邏輯,我想在現場進行額外的驗證。 示例: account_typePRIVATE並且 person_name 不為空,我想對person_name進行一些驗證(檢查它是否具有正確的格式、長度等)

您可以使用接收所有序列化字段作為參數的序列化程序的validate方法,請參見此處

您可以定義兩個序列化程序PrivateSerializerCompanySerializer然后在您看來,使用方法.get_serializer_class()並根據請求中發送的內容返回一個或另一個。

通過這種方式,您可以根據情況定義每個序列化程序驗證。

您可以使用def validate(self, data)檢查條件 required ,並使用def validate_{field_name}(self, value)進行額外驗證:

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('account_type', 'company_name', 'person_name')
        extra_kwargs = {
            'company_name': {'required': False},
            'person_name': {'required': False},
        }

    def validate(self, data):
        data_dict = dict(data)
        data_keys = data.keys()
        account_type= data_dict.get('account_type')
        if account_type == 'PRIVATE' and 'person_name' not in data_keys:
            raise serializers.ValidationError('person_name required when account_type is PRIVATE.')
        if account_type == 'COMPANY' and 'company_name' not in data_keys:
            raise serializers.ValidationError('company_name required when account_type is COMPANY.')
        return data

    def validate_person_name(self, value):
        if len(value) < 10:
            raise serializers.ValidationError('person_name must be at least 10 characters.')
        return value

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM