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

如何在Mixin的dispatch方法中访问对象?代码报错无object属性求解

问题:Mixin验证对象所有者时出现'TweetsUpdateView' object has no attribute 'object'错误

我尝试用Mixin验证请求者是否为对象所有者(owner是模型字段),但运行时报错:'TweetsUpdateView' object has no attribute 'object'

模型代码

class Tweets(models.Model):
    description = models.TextField(blank=True, null=False, default="", max_length=255)
    createdAt = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    updatedAt = models.DateTimeField(auto_now=True)

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name="owner_tweets_set",
    )
    user_likes = models.ManyToManyField(settings.AUTH_USER_MODEL)

视图代码

class OwnerRequiredMixin(UserPassesTestMixin):
    def dispatch(self, request, *args, **kwargs):
        if self.object.owner != self.request.user:
            return HttpResponseForbidden()
        return super(OwnerRequiredMixin, self).dispatch(request, *args, **kwargs)


class TweetsUpdateView(
    LoginRequiredMixin,
    OwnerRequiredMixin,
    UpdateView,
):
    model = Tweets
    template_name_suffix = "_form"
    form_class = TweetForm

    def form_invalid(self, form):
        print("form is invalid")
        return HttpResponse("form is invalid.. this is just an HttpResponse object")

    success_url = reverse_lazy("tweets:twitter")

错误原因

UpdateView的object属性是在get_object()方法执行后才被赋值的,你在OwnerRequiredMixin的dispatch方法里直接访问self.object时,这个属性还没初始化,所以会抛出属性不存在的错误。另外,你继承了UserPassesTestMixin却没使用它的核心方法test_func(),而是直接重写dispatch,不符合该Mixin的设计规范。

修复方案

方案1:使用UserPassesTestMixin的test_func(推荐)

修改OwnerRequiredMixin,利用test_func()做权限验证,同时先获取对象:

class OwnerRequiredMixin(UserPassesTestMixin):
    def test_func(self):
        # 获取当前操作的对象
        self.object = self.get_object()
        # 验证当前用户是否为对象所有者
        return self.object.owner == self.request.user
    
    # 可选:自定义无权限时的响应
    def handle_no_permission(self):
        return HttpResponseForbidden()

方案2:修改dispatch方法手动获取对象

如果坚持用dispatch,需要先手动获取对象再做验证:

class OwnerRequiredMixin(UserPassesTestMixin):
    def dispatch(self, request, *args, **kwargs):
        # 先调用get_object()初始化self.object
        self.object = self.get_object()
        if self.object.owner != self.request.user:
            return HttpResponseForbidden()
        return super().dispatch(request, *args, **kwargs)

注意:Mixin继承顺序要正确,OwnerRequiredMixin需放在UpdateView之前,你当前的继承顺序是正确的,LoginRequiredMixin保持在最前面即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 09:54:19