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

在Django REST framework中获取用户报错:User匹配查询不存在

解决Django REST framework中PDFTemplateView获取用户报错的问题

先帮你梳理清楚问题根源,再给出可行的解决方案:

1. 为什么会出现「User matching query does not exist」错误?

你用的PDFTemplateView是Django原生的类视图,并非DRF的APIView子类,所以你设置的DRF权限类permission_classes = (IsAuthenticated,)根本不会生效!

这就导致:即使用户未登录,也能访问这个视图,此时self.request.user是AnonymousUser(匿名用户),它的id为None。你执行User.objects.get(id=self.request.user.id)相当于查询id=None的用户,数据库里不存在这类用户,自然抛出了错误。

另外还有个没必要的操作:完全不用去数据库重新查询用户!如果用户已登录,self.request.user本身就是认证后的User实例,直接使用即可,多此一举的数据库查询反而会引发问题。

2. 具体解决方案

方法一:用Django原生机制强制用户登录

给视图添加login_required装饰器,确保只有登录用户才能访问,同时直接使用request.user:

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic.base import PDFTemplateView

class ListPDF(PDFTemplateView):
    """ Return a PDF """
    template_name = 'pdf.html'

    # 用method_decorator给类视图添加登录校验
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 直接使用已认证的request.user,无需查询数据库
        context['user'] = self.request.user
        return context

方法二:适配DRF的TokenAuthentication(如果需要保留Token认证)

由于PDFTemplateView不支持DRF的认证机制,需要手动在dispatch方法中处理Token验证:

from django.views.generic.base import PDFTemplateView
from rest_framework.authentication import TokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.http import HttpResponse

class ListPDF(PDFTemplateView):
    """ Return a PDF """
    template_name = 'pdf.html'

    def dispatch(self, request, *args, **kwargs):
        # 手动初始化DRF的Token认证器
        auth = TokenAuthentication()
        try:
            # 验证请求中的Token,获取用户和Token对象
            user, token = auth.authenticate(request)
            # 将认证后的用户绑定到request上
            request.user = user
            request.auth = token
        except AuthenticationFailed:
            # 认证失败时返回401,或根据需求重定向到登录页
            return HttpResponse("Unauthorized", status=401)
        return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['user'] = self.request.user
        return context

这样修改后,未登录或Token无效的请求会被拦截,你也能安全获取到已认证的用户了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:48:08