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 model:
class Comment(models.Model):
commenter = models.ManyToManyField(Commenter)
email = models.EmailField(max_length=100)
author = models.CharField(max_length=100)
url = models.URLField(max_length=200)
content = models.TextField(blank=True, null=True)
ip = models.IPAddressField(max_length=45)
date = models.DateTimeField(default=datetime.now)
post_title = models.CharField(max_length=200)
post_url = models.URLField(max_length=200)
rating = models.IntegerField(max_length=10, default=0)
Here is my API view:
class CommentNewView(CreateAPIView):
model = Comment
serializer_class = CommentCreateSerializer
Here is my serializer:
class CommentCreateSerializer(serializers.ModelSerializer):
commenter_pw = serializers.CharField(max_length=32, required=False)
class Meta:
model = Comment
fields = ('email', 'author', 'url', 'content', 'ip', 'post_title', 'post_url', 'commenter_pw')
Here is the error I am getting:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/api/comment/create/
Django Version: 1.5.2
Python Version: 2.7.2
Installed Applications:
('commentflow.apps.dashboard',
'commentflow.apps.commenter',
'commentflow.apps.comment',
'rest_framework',
'rest_framework.authtoken',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
327. response = self.handle_exception(exc)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
324. response = handler(request, *args, **kwargs)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/generics.py" in post
372. return self.create(request, *args, **kwargs)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/mixins.py" in create
50. if serializer.is_valid():
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/serializers.py" in is_valid
479. return not self.errors
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/serializers.py" in errors
471. ret = self.from_native(data, files)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/serializers.py" in from_native
867. instance = super(ModelSerializer, self).from_native(data, files)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/serializers.py" in from_native
324. return self.restore_object(attrs, instance=getattr(self, 'object', None))
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/rest_framework/serializers.py" in restore_object
852. instance = self.opts.model(**attrs)
File "/Users/tlovett1/.virtualenvs/commentflow/lib/python2.7/site-packages/django/db/models/base.py" in __init__
415. raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
Exception Type: TypeError at /api/comment/create/
Exception Value: 'commenter_pw' is an invalid keyword argument for this function
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
What you can do is to overwrite the
pre_save
orcreate
function and take out thecommenter_pw
from the data fields that are sent (not sure, but you can probably take it out formrequest.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).
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:
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.