如何实现仅订单用户可访问PDF下载链接?(含代码排查)
实现仅订单用户可访问PDF下载的方案
你的原视图函数存在逻辑错误,导致无法正确判断用户是否有订单,以下是修正后的实现:
修正后的视图函数
@login_required def secure_pdf(request, file): # 当前登录用户直接通过request.user获取,无需额外查询 current_user = request.user # 检查该用户是否存在对应的Order记录,用exists()高效判断 has_order = Order.objects.filter(user=current_user).exists() if has_order: document = get_object_or_404(Exam, pdf=f'pdf/{file}') # 可选优化:设置响应头让浏览器识别为下载文件 response = FileResponse(document.pdf) response['Content-Disposition'] = f'attachment; filename="{document.pdf.name.split("/")[-1]}"' return response else: return HttpResponse("访问被拒绝")
原代码的问题说明
- 用户获取错误:原代码用
get_object_or_404(User)会直接抛出404(因为没有指定查询条件),应该用request.user获取当前登录的用户(@login_required已经确保用户已登录)。 - 存在性判断错误:
order = Order.objects.filter(user=user).all()得到的是Order对象的集合,if user in order是判断User对象是否在Order对象集合里,逻辑完全错误,永远会返回False,导致所有用户都被拒绝访问。改用exists()直接查询数据库是否存在该用户的订单,既高效又准确。
额外优化建议
- 如果需要更严格的控制(比如用户必须有已完成的订单才能下载),可以在filter里添加状态判断:
Order.objects.filter(user=current_user, status='已完成').exists(),具体根据你的业务需求调整status的取值。 - 添加
Content-Disposition响应头,让浏览器触发下载行为,而不是直接在浏览器打开PDF,提升用户体验。
内容的提问来源于stack exchange,提问作者Onderi
相关产品推荐
相关产品推荐

