Creating Python APIs - The Django REST framework. Building a Reddit clone - Deleting Posts.[9/n]

Congratulations! Now you're on the final part of successfully creating your very own basic reddit clone.

Now for whatever reason, if the user wants to delete his post he should be able to. Let's give him that ability.

We need an url for that, so we go to the urls.py file and add the url

path('api/posts/<int:pk>', views.PostRetrieveDestroy.as_view()),

image.png

Notice the new view, PostRetrieveDestroyView which we have not defined yet. We will do that in the views.py next.

You can read about PostRetrieveDestroyView here, and if you go through the documentation you'll also notive there's another view RetrieveUpdateDestroyAPIView which might seem more suitable for this. Basically PostRetrieveDestroyView gives you an option to view and delete a post and RetrieveUpdateDestroyAPIView gives you an option to view, update and delete functionality. As you know on Reddit, you cannot edit posts, you have delete your post and create another one. Twitter follows the same, it's because if you create a sensible post that becomes viral, you would have the ability to edit the post to be something unsavory.

Now, we add the PostRetrieveDestroyView, you can use RetrieveUpdateDestroyAPIView as well if you want the users to be able to edit their posts.

image.png

Since it is Post, we can use the same options in class PostRetrieveDestroy as we had in class PostList

Now if you save this and refresh the webpage, this works. But there is a caveat, let me show you:

These are the current posts we have, as you can see we have 3 posts and we are logged in as the user Saurav.

image.png

What if I want to delete the 2nd post, let's try deleting it.

We'll use the url http://localhost:8000/api/posts/3

Notice the ID for the post is '3', although the post is 2nd. Be careful with the IDs, they should be the one in url and not the post number.

image.png

Now click on delete, it will ask if you absolutely want to delete the post. Click on delete.

image.png

Now if you go to the main page with all the posts, you should see only two posts.

image.png

Let's login as the other user we created(gaurav) and try to delete a post created by him.

image.png

If you come to the main page now and refresh, you should be able to see all the posts created by Saurav and Gaurav on the same page.

Let's try to delete the post we just created using Gaurav's ID.

image.png

Notice Gaurav's post ID is 8, make sure you put the correct ID in the url. The url should be http://localhost:8000/api/posts/8

Now, click on delete and voilà!

image.png

The post is successfully deleted, you can check on the homepage as well.

image.png

So it is successful, we can delete the post. and it works for all users as well.

Something that is an issue is if you try to delete another user's post. Let's say Gaurav wants to delete a post Saurav created. What would happen?

image.png

Gaurav wants to delete the 3rd post by Saurav. Let's see if he can delete. What do you think should happen?

image.png

It got deleted!

image.png

There's only one post that remains now.

Why do you think Gaurav was able to delete Saurav's post?

Think, we've already covered this.

Gaurav is able to delete Saurav's post is because although we've set the permission as "Authenticated or Readonly". Which means to delete the post you need to be authenticated, or you have only read access. We do not check if the user that is making the delete request is the same as the one currently logged in.

Let's fix that!

Add a delete function for the PostRetrieveDestroy class.

image.png

It is very straightforward, you define a post variable where you assign the primary key to that of the post and the poster to be the user making the request. If post exists, meaning the user logged in is the user that has created the post with the id, then we invoke the destroy function, else we raise a validation error.

To test this works, I've created a new post logged in as user Gaurav, now let's try to delete it logged in as Saurav.

image.png

The id for the post is 9, so the url should be http://localhost:8000/api/posts/9

image.png

Let's try to delete that post.

image.png

Look at that! It is working perfectly now. It crosschecks the user that is logged in with the user that is making the request.

How awesome is that? Congratulations! You have successfully created a basic reddit clone.

Next, we will add an API to an existing project.