I have a model Comment that when created may or may not create a new user. For this reason, my API requires a password field when creating a new comment. Here is my Comment
If anyone is curious, the solution is to override the restore_object method and add the extra instance variable to the comment object after it has been instantiated:
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.email = attrs.get('email', instance.email)
instance.author = attrs.get('author', instance.author)
instance.url = attrs.get('url', instance.url)
instance.content = attrs.get('content', instance.content)
instance.ip = attrs.get('ip', instance.ip)
instance.post_title = attrs.get('post_title', instance.post_title)
instance.post_url = attrs.get('post_url', instance.post_url)
return instance
commenter_pw = attrs.get('commenter_pw')
del attrs['commenter_pw']
comment = Comment(**attrs)
comment.commenter_password = commenter_pw
return comment
Thanks for your own answer, it helped me a lot :)
But I think this is a bit more generic, since I still want to call the method on the super serializer class
def restore_object(self, attrs, instance=None):
'''
we have to ensure that the temporary_password is attached to the model
even though it is no field
'''
commenter_pw = attrs.pop('comment_pw', None)
obj = super(
CommentCreateSerializer, self
).restore_object(attrs, instance=instance)
if commenter_pw:
obj.commenter_pw = commenter_pw
return obj
What you can do is to overwrite the pre_save
or create
function and take out the commenter_pw
from the data fields that are sent (not sure, but you can probably take it out form request.POST
or after you have serialized it), so the framework should not rise the error.
Plus, if you have additional logic you can implement it there before saving it (such as the one for checking if the user have to be created or what).
Previous answers didn't work on DRF3.0, the restore_object() method is now deprecated.
The solution I have used is awful but I have not found a better one. I have put a dummy getter/setter for this field on the model, this allows to use this field as any other on the model.
Remember to set the field as write_only on serializer definition.
class Comment(models.Model):
@property
def commenter_pw():
return None
@commenter_pw.setter
def commenter_pw(self, value):
pass
class CommentCreateSerializer(serializers.ModelSerializer):
commenter_pw = serializers.CharField(max_length=32, write_only=True, required=False)
class Meta:
model = Comment
fields = ('email', 'author', 'url', 'content', 'ip', 'post_title', 'post_url', 'commenter_pw')