I am building a small blog using django.I want to build a function that allow post author to delete and update their own posts. Then I find django has LoginMixin for generic view,but it only block those who don’t login.
My article Model is like below
class Article(models.Model): author = models.ForeignKey(User) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=50) context = models.TextField() genre_choice = (('O','Others'),('P','Programming'),('L','Learning'),('E','Entertainment')) genre = models.CharField(max_length=2,choices=genre_choice,default='O') def __str__(self): return "{} - {}".format(self.title,self.author) def get_absolute_url(self): return reverse("article-detail",args=str(self.id))
This is the generic article detail view.
class ArticleDetail(DetailView): model = Article
I firstly want to add something like this in the detail template:
{% if article.author == user.username%} <!-- Some a tag that directs to the update view --> {% endif %}
Then I realize that this just hides the a tag ,it can’t stop other users to touch the update url simply change the url.
Is there anyway in django can restricted the update and delete permissions to the original user by simply using generic view?Even if they directly enter the update url,they will be rejected.
Advertisement
Answer
Override get_queryset
in your UpdateView
, so that the user can only access items that they authored. Use the LoginRequiredMixin
to ensure that only logged-in users can access the view.
from django.contrib.auth.mixins import LoginRequiredMixin class UpdateArticle(LoginRequiredMixin, UpdateView): model = Article def get_queryset(self): queryset = super(UpdateArticle, self).get_queryset() queryset = queryset.filter(author=self.request.user) return queryset
In the template, I would compare the author_id
with the user’s primary key to decide whether to show the link or not.
{% if article.author_id == user.pk %}