如何在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
相关产品推荐
相关产品推荐

