我必须序列化电子邮件地址列表。如果其中一个包含错误的字符(在一种情况下,其末尾是一个“:”),我的序列化器将引发错误,拒绝序列化整个地址集并返回HTTP 400。从列表中“弹出”错误的电子邮件地址,但仍然序列化其余正确的地址?
@action(detail=False, methods=['post'])
def match(self, request):
serializer = FriendFinderSerializer(data=request.data, many=True)
if serializer.is_valid():
contacts = serializer.validated_data
matched, unmatched = self.match_contacts(contacts)
serialized_matched = FriendFinderSerializer(matched, many=True)
serialized_unmatched = FriendFinderSerializer(unmatched, many=True)
data = {
'matched': serialized_matched.data,
'unmatched': serialized_unmatched.data,
}
return Response(data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class FriendFinderSerializer(serializers.Serializer):
id = serializers.IntegerField(required=False)
image = serializers.ImageField(required=False)
record_id = serializers.CharField()
phone_numbers = serializers.ListField(child=serializers.CharField(), required=False)
email_addresses = serializers.ListField(child=serializers.EmailField(), required=False)
relationship_id = serializers.CharField(required=False)
relationship_status = serializers.CharField(required=False)
答案 0 :(得分:1)
一个开始的地方是遍历request.data
并处理循环中的每个元素。这绝对是对常规的突破,您需要确定如何处理好数据和坏数据的情况。
@action(detail=False, methods=['post'])
def match(self, request):
successful_data = []
error_data = []
for element in request.data:
serializer = FriendFinderSerializer(data=element, many=False)
if serializer.is_valid():
contacts = serializer.validated_data
matched, unmatched = self.match_contacts(contacts)
serialized_matched = FriendFinderSerializer(matched, many=True)
serialized_unmatched = FriendFinderSerializer(unmatched, many=True)
successful_data.append({
'matched': serialized_matched.data,
'unmatched': serialized_unmatched.data,
})
else:
error_data.append(serializer.errors)
# Determine what status to return and how to handle successes and errors.
就个人而言,我要么发出较小的请求,要么发布所有数据,或者处理一个FriendFinderSerializer
中的错误导致全部失败的情况。您尝试执行的操作可能会比其他选择引起更多的痛苦。
答案 1 :(得分:0)
这是一种骇客,但可以。
您需要定义一个自定义字段,并且那里需要覆盖该字段的/messages
方法。像这样:
to_internal_value
或像这样覆盖class CustomField(serializers.Field):
def __init__(self, custom_validation, *args, **kwargs):
self.custom_validation=custom_validation # <-- Here pass your custom validation regex
super(CustomField, self).__init__(*args, **kwargs)
def to_representation(self, obj):
return obj
def to_internal_value(self, obj):
try:
match = re.search(self.custom_validation, obj) # <-- validate the value against regex
if match:
return obj
except Exception as e:
pass
return None # <-- If exception occurs, return None
:
EmailField
像这样在序列化器中使用它:
class CustomEmailField(serializer.EmailField):
def run_validation(self,*args, **kwargs):
try:
return super(CustomEmailField, self).run_validation(*args,**kwargs) # <-- Runs validation, but it fails, returns None
except:
return None
或
email = CustomField(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)") # regex for email
如果要从email = CustomEmailField()
中弹出无效值,则可以像这样覆盖ListField
:
to_representation
然后,在序列化器中使用它:
class CustomListField(serializers.ListField):
def to_representation(self, data):
childs = super(CustomListField, self).to_representation(data)
new_childs = []
for child in childs:
if child:
new_childs.append(child)
return new_childs