Django DetailView出现object is not callable错误排查
问题根源
你代码的报错由两个不符合Django类视图规范的写法导致:
- 你给
get_queryset方法加了@property装饰器。Django的DetailView内部会执行self.get_queryset()调用获取查询集,加了@property后self.get_queryset会直接返回你定义的Pet实例,再对该实例执行()调用就触发了object is not callable错误。 get_queryset要求返回DjangoQuerySet对象,你直接返回了get()得到的单个Pet实例,就算去掉@property装饰器也无法通过后续的查询集处理逻辑。
你提到的打印pet得到Leo而非<Pet:Leo>是正常现象:print()会自动调用对象的__str__方法,你的Pet模型__str__定义为返回first_name,而Python shell中直接输入变量名会调用__repr__方法,因此显示格式不同,这不是报错诱因。
正确实现方案
你要实现「仅当前登录用户可访问自己的宠物详情」的需求,有两种规范写法可选:
方案1:重写get_queryset(推荐,符合类视图设计逻辑)
DetailView会自动根据url中的pk参数从你返回的查询集中过滤出单个对象,如果对象不存在会直接返回404,天然满足越权访问拦截需求:
class PetDetailView(LoginRequiredMixin, generic.DetailView): model = Pet def get_queryset(self): pet_owner = PetOwner.objects.get(user=self.request.user) return pet_owner.pet_set.all()
方案2:重写get_object(适合需要自定义单对象获取逻辑的场景)
如果你需要自行控制单对象的查询逻辑,可以重写get_object方法:
class PetDetailView(LoginRequiredMixin, generic.DetailView): model = Pet def get_object(self, queryset=None): pet_owner = PetOwner.objects.get(user=self.request.user) return pet_owner.pet_set.get(pk=self.kwargs["pk"])
内容的提问来源于stack exchange,提问作者The silent one
相关产品推荐
相关产品推荐

