有条件地需要Django DRF Serializer字段

时间:2018-04-12 21:02:29

标签: django django-rest-framework

我有一个看起来像这样的序列化器:

class MySerializer(serializers.Serializer):
    lat = serializers.FloatField(required=False)
    lng = serializers.FloatField(required=False)

我想确保如果请求附带了' lat'领域,' lng'字段将是强制性的,反之亦然。

我可以使用验证功能,但相信有更好的方法。

2 个答案:

答案 0 :(得分:6)

您应该使用序列化程序validate方法进行检查。

class MySerializer(serializers.ModelSerializer):
    lat = serializers.FloatField(required=False)
    lng = serializers.FloatField(required=False)

    def validate(self, data):
        if not data['lat'] and not data['lng']:
            raise serializers.ValidationError("They are both required.")
    return data

参考:http://www.django-rest-framework.org/api-guide/serializers/#object-level-validation

答案 1 :(得分:2)

这是一个如何将Mixin写入Serializer的示例,这将允许有条件必填字段。有关示例,请参见docstring

class ConditionalRequiredMixin:
    """
    Adds flexibility to required fields by setting up `conditional_required_fields`

    For example
        conditional_required_fields = [
        ('is_blind': {
            'condition': False,
            'required_fields': ['clock', 'naming', 'alternate_trail_making', 'cube_drawing']
        }),
        ('is_blind': {
            'condition': True,
            'required_fields': ['clock2', 'naming2',]
        })
    ]

    If is_blind will be False -> fields specified in required_fields will be required

    """
    REQUIRED_MSG = ['Field is required']
    conditional_required_fields = []

    def validate(self, attrs):
        attrs = super().validate(attrs)
        for master_field, conditions in self.conditional_required_fields:
            master_field_value = attrs.get(master_field)
            condition = conditions['condition']
            if not isinstance(condition, str) and isinstance(condition, collections.Iterable):
                trigger = master_field_value in condition
            else:
                trigger = master_field_value == condition

            if trigger:
                additional_required_fields = conditions['required_fields']
                absent_fields = [f for f in additional_required_fields if attrs.get(f) is None]
                if absent_fields:
                    error_dict = {f: self.REQUIRED_MSG for f in absent_fields}
                    raise serializers.ValidationError(error_dict)
        return attrs
相关问题