Rahul
Rahul

Reputation: 141

Allow only the author of the post to edit in class based views- Django?

views.py

class EditPost(UserPassesTestMixin, LoginRequiredMixin, UpdateView):
    model = Posts
    form_class = PostForm
    template_name="posts/add_post.html"

    def test_func(self):
        x = self.request.user.pk
        print (x)
        y = Posts.objects.get(user='user')
        print (y)
        if x == y:
            return True
        else:
            if self.request.user.is_authenticated():
                raise Http404("You are not allowed to edit this Post")

models.py

class Posts(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    post = models.CharField(max_length=1200, blank=False)

How do i match the loggedin user and the user object of the Post

i could not find any solution since i am using class based views.

Upvotes: 0

Views: 2858

Answers (3)

Cro-kris
Cro-kris

Reputation: 21

To add to the previous posts, try this:

Add to your class EditPost:

login_url = 'your url name or path to login page'
def test_func(self):
    obj = self.get_object()
    return obj.author == self.request.user

The test_func method is used by UserPassesTestMixin for this particular logic. To override it we set variable obj to the current object returned by the view using get.object(). After that, if the author on the current object (obj.author) matches the current user (self.request.user) we allow editing. If not (i.e. false) we throw an error.

login_url is from LoginRequiredMixin and the default location is /accounts/login. To override it, set your own path or name of the login template. This will take those people who are not logged in to the login page.

Upvotes: 2

Sascha Rau
Sascha Rau

Reputation: 357

try this:

add dispatch to EditPost class

def dispatch(self, request, *args, **kwargs):
    obj = self.get_object()
    if obj.user != self.request.user:
        raise Http404("You are not allowed to edit this Post")
    return super(EditPost, self).dispatch(request, *args, **kwargs)

Upvotes: 4

Alasdair
Alasdair

Reputation: 308919

Doing the check in test_func is tricky. You need to fetch the object once in test_func to check whether the user is allowed to use it, and then the object is fetched again by the same fiew.

An easier approach is to override the get_queryset method. If the user is not the author of the post, they will get a 404.

class EditPost(LoginRequiredMixin, UpdateView):
    def get_queryset(self):
        return super(EditPost, self).filter(user=self.request.user)

Upvotes: 2

Related Questions