You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django UpdateView中仅允许文章作者访问文章更新页面

嘿,要实现只有文章作者能访问更新页面的需求,Django给了咱们两种很实用的方案,我给你拆解一下:

方案一:使用UserPassesTestMixin(推荐)

Django自带的UserPassesTestMixin专门用来做这种基于用户的权限校验,咱们只需要把它加到你的类视图继承列表里,再重写test_func方法就行。注意Mixin的顺序要对——先继承LoginRequiredMixin(保证用户已登录),再继承UserPassesTestMixin(做权限校验),最后才是UpdateView,因为Django会从左到右执行Mixin的逻辑。

修改后的完整代码如下:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic.edit import UpdateView
from .models import Article, StocksETFsBonds, Tag
from django.db.models import Count

class ArticleUpdate(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Article
    template_name = 'articles/update_view.html'
    context_object_name = 'article_update'
    form_class = ArticleForm

    def test_func(self):
        # 获取当前要编辑的文章对象
        article = self.get_object()
        # 校验:当前登录用户是否等于文章的作者
        return self.request.user == article.author

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['securities_types_list'] = StocksETFsBonds.objects.all()
        context['tags_list'] = Tag.objects.annotate(articles_quantiy=Count('taggit_taggeditem_items')).order_by('-articles_quantiy')[:10]
        return context

如果权限校验不通过,Django会默认返回403 Forbidden页面。如果你想自定义这个页面的内容,可以重写handle_no_permission方法。

方案二:重写get_object方法

另一种方式是直接在获取文章对象的时候做权限校验,这种方式更直接,适合不想多继承一个Mixin的场景。我们只需要重写get_object方法,在拿到文章后判断用户是否是作者,不是的话抛出PermissionDenied异常。

代码示例:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import UpdateView
from django.core.exceptions import PermissionDenied
from .models import Article, StocksETFsBonds, Tag
from django.db.models import Count

class ArticleUpdate(LoginRequiredMixin, UpdateView):
    model = Article
    template_name = 'articles/update_view.html'
    context_object_name = 'article_update'
    form_class = ArticleForm

    def get_object(self, queryset=None):
        # 先调用父类方法获取文章对象
        article = super().get_object(queryset=queryset)
        # 校验权限:如果当前用户不是作者,抛出权限异常
        if article.author != self.request.user:
            raise PermissionDenied("你没有权限修改这篇文章")
        return article

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['securities_types_list'] = StocksETFsBonds.objects.all()
        context['tags_list'] = Tag.objects.annotate(articles_quantiy=Count('taggit_taggeditem_items')).order_by('-articles_quantiy')[:10]
        return context

这种方法的好处是在获取对象的第一环节就拦截了无权限的请求,避免后续不必要的处理,而且可以自定义异常提示语。

注意事项

要确保你的Article模型里有一个author字段,关联到Django的User模型,比如:

from django.db import models
from django.contrib.auth.models import User

class Article(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='articles')
    title = models.CharField(max_length=200)
    content = models.TextField()
    # 其他字段...

内容的提问来源于stack exchange,提问作者ilsurealism

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 08:07:44