【问题标题】:Django rest framework serializer: required_fieldsDjango rest 框架序列化器:required_fields
【发布时间】:2020-03-22 07:27:44
【问题描述】:

是否可以在序列化程序中将必填字段设置为列表? 我不想像这样在每一行中用它们的类型覆盖每个字段:

    name = serializers.CharField(required=True)
    description = serializers.CharField(required=True)
    date_start = serializers.DateTimeField(required=True)
    date_end = serializers.DateTimeField(required=True)

我只想列举字段名

class CampaignStepFirstSerializer(serializers.ModelSerializer):
    class Meta:
        model = Campaign
        fields = (
            'name',
            'description',
            'date_start',
            'date_end',
        )
        required_fields = fields

【问题讨论】:

  • 是的,这是 DRF

标签: python django django-rest-framework serialization


【解决方案1】:

如果模型字段是用null=Trueblank=True实例化的,或者模型字段有默认值,序列化器会自动将对应的字段设置为required=False。 (见rest_framework.utils.field_mapping.get_field_kwargs的来源)。

如果您需要覆盖此行为,可以这样做:

class CampaignStepFirstSerializer(serializers.ModelSerializer):
    class Meta:
        model = Campaign
        fields = (
            'name',
            'description',
            'date_start',
            'date_end',
        )

        # 1st option. If some fields are required
        extra_kwargs = {
            'name': {'required': True},
            'description': {'required': True},
            'date_start': {'required': True},
            'date_end': {'required': True},
        }

        # 2nd option. If all the fields are required:
        extra_kwargs = {i:{'required': True} for i in fields}

【讨论】:

    【解决方案2】:

    DRF 中没有这样的选项。与Meta 最接近的是extra_kwargs(假设您使用的是serializers.ModelSerializer),分别提及字段名称,值是{'required': True} 的字典。但这比在初始化字段时明确提及required=True 更有效。


    你可以通过对serializers.Serializersget_fields 方法和任何子类(例如serializers.ModelSerializer)的一点点扩展来获得你想要的:

    class CampaignStepFirstSerializer(serializers.ModelSerializer):
    
        def get_fields(self):
    
            fields = super().get_fields()
    
            try:
                required_fields = self.Meta.required_fields
            except AttributeError:
                return fields
    
            if not isinstance(required_fields, (list, tuple)):
                raise TypeError(
                    'The value of `Meta.required_fields` option must be a list or tuple.'
                )
    
            for field_name in required_fields:
                try:
                    field = fields[field_name]
                except KeyError:
                    continue
    
                if (
                        not field.read_only and
                        field.default is serializers.empty
                ):
                    field.required = True
                    fields[field_name] = field
    
            return fields
    
        class Meta:
            model = Campaign
            fields = (
                'name',
                'description',
                'date_start',
                'date_end',
            )
            required_fields = fields
    

    如图所示,在序列化程序类的Meta 类中,您可以定义required_fields 选项,如果这些字段不是read_only 并且没有默认值,则这些字段将被设为required

    需要注意的是,如果您在序列化程序上使用required=False 显式定义了某些字段,并且还提到了Meta.required_fields 中的字段,则__repr__ 将显示required=False(例如,当您将检查<serializer_instance>.fields)。 serializers.Field.__repr__ is defined such that the initial arguments used in the creation of a field are shown as-is。构造函数 (Field.__new__) 保留 _kwargs 属性以保留初始参数。

    这适用于所有显式声明的字段(元类serializers.SerailizerMetaclass 在序列化程序类上设置_declared_fields 属性),因此使用read_only_fields/write_only_fields/extra_kwargsMeta 选项也不会影响表示。

    如果您愿意,您可以覆盖该字段的 __repr__ 来更改此设置,但我认为您不应该这样做,因为这会破坏与其余设计的一致性。

    【讨论】:

      猜你喜欢
      • 2015-06-29
      • 2015-10-29
      • 2020-05-08
      • 2018-12-13
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-11
      相关资源
      最近更新 更多