0

I'm working on a Rest API for a web blog, I have made the custom user class and related between custom user class and the post class, but when i try to make a post request and add a post to the database i'm stuck in serializering the post because of the the relation between the user and the post models, all i want to do is just make the author of the post is the current logged in user but i don't actually know how to do this

Custom user model:

class CustomUser(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(max_length=255, unique=True, blank=False, null=False)
    username = models.CharField(max_length=255, unique=True, blank=False, null=False)
    date_joined = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)
    is_superuser = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    objects = CustomUserManager()

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return self.is_superuser

Post model:

class Post(models.Model):
    title = models.CharField(max_length=255, blank=False, null=False)
    content = models.CharField(max_length=10000, blank=False, null=False)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

Post serializer:

class PostSerializer(ModelSerializer):


    class Meta:
        model = Post
        # I don't know if this way is right
        fields = ('id', 'title', 'content', 'author')
        extra_kwargs = {"author": {"read_only": True}}

    def create(self, validated_data, request):
        post = Post(
            title=validated_data['title'],
            content=validated_data['content'],
            # I don't know what's gonna be assigned to the author
            author=
        )
        post.save()
        return post

Post View:

class AddPostView(APIView):

    serializer_class = serializers.PostSerializer

    def post(self, request):
        serializer = serializers.PostSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(data=serializer.data)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
KickItLikeShika
  • 33
  • 1
  • 1
  • 6

2 Answers2

0

At first, it doesn't seem to me like you need to specify your custom create method in PostSerializer. And author field can't be read_only otherwise it will be ignored and won't be saved. So it could just look like this:

class PostSerializer(ModelSerializer):
  class Meta:
    model = Post
    fields = ('id', 'title', 'content', 'author')

Then this is how you assign an author in your view action:

def post(self, request):
  current_user = request.user
  serializer = serializers.PostSerializer(data={**request.data, author=current_user})
  ...
GProst
  • 9,229
  • 3
  • 25
  • 47
0

I found a way that works fine for me. Pass the context to the serializer from the view Post View:

class AddPostView(APIView):

serializer_class = serializers.PostSerializer

def post(self, request):
    serializer = serializers.PostSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        serializer.save()
        return Response(data=serializer.data)

    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Then here is the serializer. Post Serializer

class PostSerializer(ModelSerializer):

    class Meta:
        model = Post
        fields = ('id', 'title', 'content', 'author')
        extra_kwargs = {"author": {"read_only": True}}

    def create(self, validated_data):
        user = self.context['request'].user
        post = Post(
            title=validated_data['title'],
            content=validated_data['content'],
            author=user
        )
        post.save()
        return post
KickItLikeShika
  • 33
  • 1
  • 1
  • 6