我有一个看起来像这样的序列化器:
class MySerializer(serializers.Serializer):
lat = serializers.FloatField(required=False)
lng = serializers.FloatField(required=False)
我想确保如果请求附带了' lat'领域,' lng'字段将是强制性的,反之亦然。
我可以使用验证功能,但相信有更好的方法。
答案 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