DRF: delete the field in the model serializer after validation, but before creation (on CreateAPIView)

I have a contact form on a site that sends to CreateAPIView to create a new instance of the model (which, ultimately, is sent to the administrator by email). On my serializer, I have a honeypot field to help cancel spam.

Model:

 class Message(models.Model): name = ... message = ... 

and serializer:

 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 

and view:

 class MessageView(generics.CreateAPIView): ''' Create a new contact form message. ''' serializer_class = MessageSerializer 

My problem is that since it appears when I send a message, I get an error message:

TypeError: It turned out <<24> when calling Message.objects.create() . This may be due to the fact that you have fields for writing to the serializer class, which is not a valid argument for Message.objects.create() . You may need to make the field read-only or override the MessageSerializer.create () method to handle it correctly.

obviously seriazlier is trying to save the url field in the model in CreateApiView.perform_create()

I tried adding read_only to the serializer field, but that means the url_validate method url_validate completely skipped.

How can I save a field in a serializer until validation happens by deleting it before serializer.save() is called in perform_create() ?

+7
django django-rest-framework
source share
2 answers

you can do this by overriding the create method, for example:

 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) 
+5
source share

OK, I read the error incorrectly. As clearly stated:

override the MessageSerializer.create () method to handle it correctly.

I was looking for a rewrite of the CreateAPIView.create() method that didn't make sense.

It works:

 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) 
0
source share

All Articles