我在发布到CreateAPIView
的网站上有一个联系表单,用于创建模型的新实例(最终通过电子邮件发送给管理员)。在我的序列化程序中,我有一个蜜罐字段来帮助拒绝垃圾邮件。
模特:
class Message(models.Model):
name = ...
message = ...
和序列化器:
class MessageSerializer(serializers.ModelSerializer):
# Honeypot field
url = serializers.CharField(allow_blank=True, required=False)
class Meta:
model = Message
fields = '__all__'
def validate_url(self, value):
if value and len(value) > 0:
raise serializers.ValidationError('Spam')
return value
并查看:
class MessageView(generics.CreateAPIView):
''' Create a new contact form message. '''
serializer_class = MessageSerializer
我的问题在于,当我发布到此视图时,我收到错误:
TypeError:调用
TypeError
时获得Message.objects.create()
。这可能是因为序列化程序类上的可写字段不是Message.objects.create()
的有效参数。您可能需要将该字段设置为只读,或覆盖MessageSerializer.create()方法以正确处理此字段。
很明显,seriazlier正在尝试将url
字段保存到CreateApiView.perform_create()
我尝试将read_only
添加到序列化程序字段,但这意味着完全跳过url_validate
方法。
如何在验证发生之前将字段保留在序列化程序中,在serializer.save()
中调用perform_create()
之前将其删除?
答案 0 :(得分:5)
你可以这样做覆盖create方法,如:
class MessageSerializer(serializers.ModelSerializer):
# Honeypot field
url = serializers.CharField(allow_blank=True, required=False)
class Meta:
model = Message
fields = '__all__'
def validate_url(self, value):
if value and len(value) > 0:
raise serializers.ValidationError('Spam')
return value
def create(self, validated_data):
data = validated_data.pop('url')
return Message.objects.create(**data)
答案 1 :(得分:0)
好的,我没有正确读取错误。正如它清楚地说:
重写MessageSerializer.create()方法以正确处理此问题。
我正在考虑覆盖那些没有意义的CreateAPIView.create()
方法。
这有效:
class MessageSerializer(serializers.ModelSerializer):
# Honeypot field
url = serializers.CharField(allow_blank=True, required=False)
class Meta:
model = Message
fields = '__all__'
def validate_url(self, value):
if value and len(value) > 0:
raise serializers.ValidationError('Error')
return value
def create(self, validated_data):
if "url" in validated_data:
del validated_data["url"]
return Message.objects.create(**validated_data)