Amin Ba
Amin Ba

Reputation: 2436

How to define permission on django views?

I have these models:

class Author(Model):
    user = OneToOneField(User, on_delete=CASCADE)
    # Fields

class Post(Model):
    author = ForeignKey(Author, on_delete=CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField()

and a few views as below:

def authors(request)
   authors = Authors.objects.all()
   return render(request, 'authors.html', {'authors': authors})

The authors' view has a corresponding url path as below:

path('authors/', authors, name='authors')

in authors.html I loop over authors and for each one, I have a link that sends the author primary key to the author url and view:

{% for author in authors%}
    <a href="{% url 'author' author_pk=author.pk %}"{{author.user.email}}</a><br><br>
{% endfor %}

Ok; Everybody is able to see the list of authors.

I then have author url path as below:

path('authors/<int:author_pk>/', author, name='author')
path('authors/<int:author_pk>/<int:post_pk>/delete/', author_delete_post, name='author_delete_post')

And I have the author view in which I show the posts each author has published and a button to delete it.

def author(request, author_pk)
    author=get_object_or_404(Author, pk=author_pk)
    author_posts = Post.objects.filter(author=author)
    return render(request, 'author.html', {'author_posts': author_posts}

@login_required
def author_delete_post(request, author_pk, post_pk):
    author=get_object_or_404(Author, pk=author_pk)
    author_post = Post.objects.get(author=author, pk=post_pk)  # I know that author=author is redundent but it makes no problem
    author_post.delete()
    return redirect(author, author_pk)

This author template:

{% for author_post in author_posts %}
{{author_post.title}}<br>
    {% if user.is_authenticated and author.user == user %}
        <a href="{% url 'author_delete_post' author_pk=author_post.author.pk post_pk=author_post.pk %}">Delete</a><br><br><br>
    {% endif %}

{% endfor %}

I am letting those authors who are logged in and are in their own page to be able to see the delete button. This is something like facebook that a user is able to delete just his/her posts, not other's.

My problem: Suppose there is an other having pk=1 and is logged in. Although he/she cannot see delete button when he/she is in this page: '/authors/2/' he/she can play with the url and delete a post of another user having pk=2

'authors/2/10/delete/'

How can I solve this problem?

Upvotes: 0

Views: 45

Answers (1)

Marcell Erasmus
Marcell Erasmus

Reputation: 914

You can use the request.user to check if the object belongs to the logged in user

Also you should not need to add the author_pk. You can get the author with author = get_object_or_404(Author, user=request.user)

@login_required
def author_delete_post(request, post_pk):
    author = get_object_or_404(Author, user=request.user)
    author_post = Post.objects.get(author=author, pk=post_pk)  # I know that author=author is redundent but it makes no problem
    # check if the post belongs to the logged in user
    if author_post.author.user == request.user:
        # delete here
    return redirect(author, author.pk)

Upvotes: 1

Related Questions