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

Django Rest Framework仅单个URL出现CSRF cookie未设置错误的原因

问题分析与解决方案

看起来这个CSRF错误的根源其实和你的视图代码里的一个小问题有关,其他表单正常是因为它们的视图没有触发这个隐藏的错误。让我一步步拆解:

核心问题:视图依赖不存在的URL参数

你的RateOpportunity视图重写了get_queryset方法,试图从self.kwargs["pk"]获取ID,但你的URL配置path("opportunities/rate/", RateOpportunity.as_view)根本没有捕获pk参数!

当Django处理这个POST请求时,视图流程中会调用get_queryset(哪怕CreateAPIView本身不需要查询集来创建对象),这时候会直接抛出KeyError异常。这个异常会干扰正常的响应流程,导致CSRF cookie没有被正确设置或返回给前端,最终触发"CSRF cookie未设置"的错误——虽然表面上看是CSRF的问题,实际上是后端视图的参数错误导致的连锁反应。

修复步骤

1. 移除多余的get_queryset方法

CreateAPIView用于创建新对象,完全不需要重写get_queryset(这个方法主要用于查询类视图,比如ListAPIView或RetrieveAPIView)。把这段代码删掉:

def get_queryset(self):
    id = self.kwargs["pk"]
    return Opportunity.objects.all().filter(opportunity=id)

2. 按需调整URL或业务逻辑

如果你确实需要在创建评分时关联某个特定的Opportunity,有两种方式:

  • 方式一:从请求体获取Opportunity ID
    在序列化器中接收opportunity_id字段,然后在perform_create中关联对象:
    class RateOpportunity(generics.CreateAPIView):
        permission_classes = [permissions.IsAuthenticated]
        serializer_class = OpportunityRateSerializer
        name = "rate-opportunity"
    
        def perform_create(self, serializer):
            # 从请求数据中获取opportunity_id,确保序列化器已定义该字段
            opportunity_id = self.request.data.get("opportunity_id")
            opportunity = Opportunity.objects.get(pk=opportunity_id)
            serializer.save(user=self.request.user, opportunity=opportunity)
    
  • 方式二:修改URL添加pk参数
    如果希望从URL路径传递Opportunity ID,修改URL配置:
    path("opportunities/rate/<int:pk>/", RateOpportunity.as_view()),
    
    然后在perform_create中获取pk:
    def perform_create(self, serializer):
        opportunity = Opportunity.objects.get(pk=self.kwargs["pk"])
        serializer.save(user=self.request.user, opportunity=opportunity)
    

3. 验证CSRF token的携带(可选)

虽然你说其他表单正常,但可以确认Vue请求是否正确携带了CSRF token:确保请求头包含X-CSRFToken,值从Django设置的csrftoken cookie中获取。比如在Vue中可以这样获取:

const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken=')).split('=')[1];
// 然后在POST请求的headers中设置:
headers: {
  'X-CSRFToken': csrfToken
}

完成以上修改后,这个端点的CSRF错误应该就会消失了——因为后端不再抛出异常,响应流程恢复正常,CSRF cookie也能正确设置和验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:21:00