Before asking this question, I have seen the following links but they don’t help me at all:
I have an author model that has foreign key to default django user model:
apps/author/models.py
class Author(models.Model): user = models.OneToOneField( User, related_name='author', on_delete=models.CASCADE, default="", ) is_author = models.BooleanField( default=True, ) full_name = models.CharField( max_length=100, default="", ) def __str__(self): return self.user.username
Post model has a foreign key to Author.
apps/posts/models.py
class Post(models.Model): author = models.ForeignKey( Author, related_name="posts", on_delete=models.CASCADE, ) title = models.TextField( null=True, blank=True, ) content = models.TextField( null=True, blank=True, ) is_draft = models.BooleanField( default=True ) created_at = models.DateTimeField( auto_now_add=True, null=True, ) published_at = models.DateField( null=True, blank=True, default=None, ) def __str__(self): return str(self.id) + ", " + self.title
Problem Definition: In order to create a new post, I am getting the current user from self.request.user
in views, and pass it to the PostSerializer. But whenever I want to create a new post using the following request to localhost:8000/posts/
I have got an error:
# I also added JWT authorization header to the postman! and it doesn't have any problem at this level { "title": "", "content": "" }
error
This is what I have done in apps/posts/views.py
:
def get_serializer_context(self): context = super().get_serializer_context() context["user"] = self.request.user context["author"] = Author.objects.get(user=context["user"]) print(context["author"]) return context
print(context["author"])
works well and prints out the current author. The problem is that I can’t get it in serializers.
class PostSerializer(serializers.ModelSerializer): # author = serializers.SerializerMethodField('get_author') # # def get_author(self, obj): # print('current author', self.context["author"]) # return self.context["author"] class Meta: model = Post fields = '__all__' extra_fields = ['author'] #def create(self, validated_data): #print(self.context["author"]) #print(self.context)
PS: The comments are the ways I have tried but the error is still occurred. How can I fix the problem?
Advertisement
Answer
UPDATE:
I was wrong, there is a simpler solution: https://stackoverflow.com/a/38167148/7285863
That should be simplest way.
class PostViewSet(viewsets.ModelViewSet): # ... other implementations def create(self, request, *args, **kwargs): serializer = self.get_serializer(data={"author": request.user.author.id, **request.data}) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def update(self, request, pk, *args, **kwargs): try: post = Post.objects.get(pk=pk) except Post.DoesNotExist: raise NotFound("Post doesn't exist.") if post.author != request.user.author: raise PermissionDenied('Permission Denied!') serializer = PostSerializer(post, data={"author": request.user.author.id, **request.data}) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return Response(serializer.data)
It’s default method except passing author
data.
You may need to check user has author
relation.