DRF Serializer - 接受字段但不要在“创建”或“更新”中使用它
DRF Serializer - Accept field but don't use it in `create` or `update`
我有一个模型 Message
,它有一个 FileField
。我的 API 接受 Base64
编码的文件,因此它们可以与其他数据一起发送。
要知道文件名和扩展名,序列化程序中还有一个字段 attachment_filename
不是模型字段。在Base64Field
.
里面使用
我希望能够验证是否同时存在 attachment_filename
、attachment
或 none。
问题是如果 attachment_filename
是只读的,它不会出现在 validate
- data
变量中。
另一方面,如果它是 required=False
、allow_null=True
,序列化程序在创建消息时会引发错误:
TypeError: ChatMessage() got an unexpected keyword argument 'attachment_filename'
代码:
class Base64File(Base64FileField): # todo make accept a list of extensions (finite eg. pdf, xlsx, csv, txt )
ALLOWED_TYPES = ['pdf', 'xlsx', 'png', 'jpg', 'jpeg', 'docx', 'doc', 'zip']
def get_file_extension(self, filename, decoded_file):
extension = self.get_full_name().split('.')[-1]
return extension
def get_file_name(self, decoded_file):
attachment_filename = self.get_full_name()
return '.'.join(attachment_filename.split('.')[:-1])
def get_full_name(self):
return self.context['request'].data['attachment_filename'] # todo validate name
class ChatMessageSerializer(serializers.ModelSerializer):
attachment = Base64File(required=False)
attachment_filename = serializers.CharField(required=False, allow_null=True)
class Meta:
model = ChatMessage
fields = '__all__'
def validate(self, data):
"""
Validation of start and end date.
"""
attachment = data.get('attachment')
attachment_filename = data.get('attachment_filename')
if bool(attachment) ^ bool(attachment_filename):
raise serializers.ValidationError("Either none or both 'attachment' and 'attachment_filename' must be present")
# del data['attachment_filename'] # works but dirty
return data
如何让它发挥作用?
编辑
我设法通过添加
使其工作
del data['attachment_filename']
在 validate
方法之前 return 但这似乎太“脏”了。
您应该在 serializer.save
方法中处理此行为,例如,您可以像这样从 validated_data
弹出它:
def save(self, **kwargs):
self.validated_data.pop("attachment_filename")
return super().save(**kwargs)
我有一个模型 Message
,它有一个 FileField
。我的 API 接受 Base64
编码的文件,因此它们可以与其他数据一起发送。
要知道文件名和扩展名,序列化程序中还有一个字段 attachment_filename
不是模型字段。在Base64Field
.
我希望能够验证是否同时存在 attachment_filename
、attachment
或 none。
问题是如果 attachment_filename
是只读的,它不会出现在 validate
- data
变量中。
另一方面,如果它是 required=False
、allow_null=True
,序列化程序在创建消息时会引发错误:
TypeError: ChatMessage() got an unexpected keyword argument 'attachment_filename'
代码:
class Base64File(Base64FileField): # todo make accept a list of extensions (finite eg. pdf, xlsx, csv, txt )
ALLOWED_TYPES = ['pdf', 'xlsx', 'png', 'jpg', 'jpeg', 'docx', 'doc', 'zip']
def get_file_extension(self, filename, decoded_file):
extension = self.get_full_name().split('.')[-1]
return extension
def get_file_name(self, decoded_file):
attachment_filename = self.get_full_name()
return '.'.join(attachment_filename.split('.')[:-1])
def get_full_name(self):
return self.context['request'].data['attachment_filename'] # todo validate name
class ChatMessageSerializer(serializers.ModelSerializer):
attachment = Base64File(required=False)
attachment_filename = serializers.CharField(required=False, allow_null=True)
class Meta:
model = ChatMessage
fields = '__all__'
def validate(self, data):
"""
Validation of start and end date.
"""
attachment = data.get('attachment')
attachment_filename = data.get('attachment_filename')
if bool(attachment) ^ bool(attachment_filename):
raise serializers.ValidationError("Either none or both 'attachment' and 'attachment_filename' must be present")
# del data['attachment_filename'] # works but dirty
return data
如何让它发挥作用?
编辑
我设法通过添加
使其工作del data['attachment_filename']
在 validate
方法之前 return 但这似乎太“脏”了。
您应该在 serializer.save
方法中处理此行为,例如,您可以像这样从 validated_data
弹出它:
def save(self, **kwargs):
self.validated_data.pop("attachment_filename")
return super().save(**kwargs)