Django中重写DetailView的get_queryset遇pk参数缺失错误求助
解决Django DetailView重写get_queryset的错误
错误原因
get_queryset要求返回QuerySet对象,但你用User.objects.get(pk=pk)返回的是单个User实例,不符合方法预期。- 代码中
pk变量未定义,URL路由捕获的pk参数需要从视图的self.kwargs字典中获取。
基础修正方案(允许查看任意用户页面)
如果只是需要根据URL的pk参数获取对应用户,修正get_queryset如下:
class UserPage(LoginRequiredMixin, DetailView): template_name = 'user_page.html' model = User login_url = '/login/' def get_queryset(self): # 从kwargs中获取URL传递的pk,返回包含该用户的QuerySet return User.objects.filter(pk=self.kwargs.get('pk'))
更安全的方案(限制用户仅查看自己的页面)
如果要确保登录用户只能访问自己的页面,可结合过滤和权限校验:
from django.core.exceptions import PermissionDenied class UserPage(LoginRequiredMixin, DetailView): template_name = 'user_page.html' model = User login_url = '/login/' def get_queryset(self): # 仅返回当前登录用户的QuerySet return User.objects.filter(pk=self.request.user.pk) def get_object(self, queryset=None): obj = super().get_object(queryset) # 校验对象是否为当前用户,否则抛出权限错误 if obj != self.request.user: raise PermissionDenied("你无权访问此页面") return obj
简化方案(无需重写get_queryset)
如果没有额外过滤需求,DetailView会自动根据URL的pk参数从model中获取对象,无需重写get_queryset:
class UserPage(LoginRequiredMixin, DetailView): template_name = 'user_page.html' model = User login_url = '/login/'
内容的提问来源于stack exchange,提问作者Mehdi
相关产品推荐
相关产品推荐

