重载get_object()并手动设置主键

5 投票
2 回答
13526 浏览
提问于 2025-04-17 21:22

我有一个叫做 DetailView 的类,在这个类里我没有传入主键(pk)或者别名(slug)。所以,我想要重写 get_object(self) 这个方法,手动添加查询过滤条件(在我的情况下,就是当前登录的用户)。不过,我没有成功:

class ViewSpecialUser(LoginRequiredMixin, DetailView):
    model = SpecialUser
    print(self)

    def get_object(self):

        object = super(ViewSpecialUser, self).get_object(queryset)
        object.queryset = queryset.filter(pk=self.request.user.pk)
        return object

    def get_context_data(self, **kwargs):
        context = super(ViewSpecialUser, self).get_context_data(**kwargs)
        return context

2 个回答

8

get_object 函数会接收一个可选的 queryset 参数,但你没有使用这个参数,所以可能会出现一个错误,提示 TypeError: get_object() takes exactly 1 argument (2 given)。即使在你的特定情况下,get_object 是没有传入 queryset 参数的,但你实际上是在尝试引用一个你从未定义过的 queryset 变量,因此你可能会看到 NameError: global name 'queryset' not defined 这个错误。

SingleObjectMixin 中的 get_object 实现会为 queryset 参数设置一个默认值,如果没有提供的话,你也应该这样做:

def get_object(self, queryset=None):
    ...
    if queryset is None:
        queryset = self.get_queryset()
    ...

然后你应该使用这个 queryset(可以是作为参数传入的,或者通过 self.get_queryset() 获取)来查找你的用户:

    return queryset.get(pk=self.request.user.pk)

当然,这里假设要么 1) SpecialUser 是你在身份验证中使用的用户模型,要么 2) 它的 pk 和你实际使用的用户模型是同步的。

9

只需要返回一个模型的实例:

def get_object(self):
    return self.model.objects.get(pk=self.request.user.pk)

撰写回答