Reputation: 625
I have Comment model related with User model
# models.py
class Comment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
more fields...
....
In the serializer I want to do a create (POST) of a user comment. But the post method is not enabled, only the put or patch method
Example: User Jon wants to create a comment
# serializers.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
class UserCommentSerializer(serializers.ModelSerializer):
# id of comment
url = serializers.HyperlinkedIdentityField(
view_name="user-comments-detail",
read_only=True
)
id = serializers.CharField(read_only=True)
comment = CommentSerializer()
class Meta:
model = User
fields = ['id', 'comment']
def create(self, validated_data):
comment_data = validated_data.pop('comment')
user = User.objects.create(**validated_data)
Comment.objects.create(user=user, **comment_data)
return user
I want to new comment, referencing the user
# views.py
class CommentViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserCommentSerializer
But I have an exception, that the user has no comment RelatedObjectDoesNotExist
My url like this
http://localhost:8000/user-comments/10
10 is a user_id pk
{} object post
Example: Comment.objects.create(user=pk, {})
Currently, only put and patch is enabled, but what I want to do is post of user
{
"url": "http://localhost:8000/user-comments/10",
"id": "10",
"comment": null
}
Comment does not exist
Any idea or suggestion?
Upvotes: 0
Views: 181
Reputation: 2006
You actually need just one serializer for that.
This will create a comment for the current logged in user.
# serializers.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
read_only_fields = ['user']
def create(self, validated_data):
# get the user who sent the request
user = self.context['request'].user
return Comment.objects.create(user=user, **validated_data)
# views.py
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
def get_serializer_context(self):
# this is important since you want to pass the request object to your serializer
context = super().get_serializer_context()
context.update({"request": self.request})
return context
Upvotes: 1
Reputation: 5452
The exception you are getting is because ModelSerializer
is linked to a specific model, in this case you linked UserCommentSerializer
to model User
. Variable Meta.fields
specifies which fields of the model are being returned by the serializer and, so, you are getting an exception because such variable is set to ('id', 'comment')
and model User
doesn't have a field comment
.
You can achieve what you want, this way:
class UserCommentSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id']
extra_kwargs = {'comment': {'write_only': True}}
def create(self, validated_data):
comment_data = validated_data.pop('comment')
user = User.objects.create(**validated_data)
Comment.objects.create(user=user, comment=comment_data)
Upvotes: 0