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

重写Django UpdateView的get()方法时出现'str'对象没有属性'get'的错误

解决Django UpdateView中返回字符串导致的AttributeError问题

错误原因分析

你遇到的'str' object has no attribute 'get'错误,核心原因是你在get()方法的else分支返回了一个字符串:reverse()函数返回的是URL路径的字符串形式,而Django视图的请求处理方法必须返回一个HttpResponse类的对象(比如HttpResponseRedirect、TemplateResponse等)。中间件在处理响应时,试图对这个字符串调用get()方法(比如检查X-Frame-Options头),自然就会报错。

另外,只重写get()方法来做权限校验是不完整的——用户可以直接构造POST请求绕过这个限制,修改不属于自己的Stats数据。

正确的解决方案:重写get_object()方法(推荐)

Django的基于类的视图(CBV)提供了get_object()方法,专门用来获取当前视图要操作的对象。重写这个方法是实现对象级权限控制的标准做法,既能限制GET请求,也能限制POST请求。

方案1:利用OneToOne关联特性(无需URL中的pk参数)

因为Stats和User是OneToOne关联,每个用户只有一个Stats对象,所以URL里不需要pk参数,直接通过当前用户获取即可:

from django.http import Http404
from django.views.generic.edit import UpdateView
from .models import Stats

class StatsUpdateView(UpdateView):
    model = Stats
    fields = ('stat1', 'stat2', 'stat3')

    def get_object(self, queryset=None):
        # 获取当前登录用户关联的Stats对象
        try:
            obj = self.request.user.stats
        except Stats.DoesNotExist:
            # 处理用户没有Stats记录的情况,比如返回404或重定向
            raise Http404("你还没有关联的统计数据")
        return obj

对应的URL配置可以简化为:

path('updatestats/', StatsUpdateView.as_view(), name='updatestats')

方案2:保留URL中的pk参数(如果有特殊需求)

如果你必须保留URL里的pk参数,重写get_object()时需要检查对象是否属于当前用户:

from django.core.exceptions import PermissionDenied
from django.views.generic.edit import UpdateView
from .models import Stats

class StatsUpdateView(UpdateView):
    model = Stats
    fields = ('stat1', 'stat2', 'stat3')

    def get_object(self, queryset=None):
        # 先调用父类方法获取对应pk的对象
        obj = super().get_object(queryset=queryset)
        # 校验对象所属用户
        if obj.user != self.request.user:
            # 可以重定向到首页,或者抛出403禁止访问错误
            # return redirect('homepage:home')
            raise PermissionDenied("你没有权限修改这条数据")
        return obj

如果你坚持要重写get()方法(不推荐)

如果一定要通过重写get()方法实现,需要返回正确的HttpResponse对象,而不是字符串。可以调用父类的get()方法来获取正常的响应,或者用redirect()(它返回的是HttpResponseRedirect对象):

def get(self, *args, **kwargs):
    stats_obj = Stats.objects.get(pk=kwargs['pk'])
    if self.request.user != stats_obj.user:
        return redirect('homepage:home')
    else:
        # 调用父类的get方法,返回合法的HttpResponse对象
        return super().get(*args, **kwargs)

额外提示

  • 永远优先使用Django CBV提供的标准钩子方法(比如get_object()、get_queryset())来做权限控制,这样代码更符合框架规范,也能覆盖所有请求方法。
  • 可以结合Django的@login_required装饰器或者LoginRequiredMixin确保只有登录用户能访问这个视图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:37:43