如何使用Python Requests向Django REST API发送POST请求
解决Django REST API POST请求403 CSRF错误的问题
你遇到的403错误确实是Django的CSRF保护机制在起作用——Django默认会对未携带正确CSRF令牌的POST请求进行拦截,所以你的请求根本没走到视图的post方法里,自然看不到打印语句。这里给你两种常用的解决方案,根据你的场景选择:
方案一:给API视图禁用CSRF保护(推荐纯API场景)
如果这个接口是专门给后端服务或客户端调用的API,不需要浏览器的CSRF防护,可以给你的ProductList视图添加csrf_exempt装饰器。因为你用的是类视图,需要用method_decorator来装饰整个类的dispatch方法:
首先导入必要的模块:
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator
然后修改你的视图类:
@method_decorator(csrf_exempt, name='dispatch') class ProductList(generics.ListAPIView): serializer_class = ProductSerializer def post(self, request, format=None): print('THIS IS A POST REQUEST') queryset = [product.name for product in Product.objects.all()] return Response(queryset)
修改后,Django就不会对这个视图的请求做CSRF检查了,你的requests.post就能正常触发post方法。
方案二:携带CSRF令牌发送请求(适合模拟浏览器场景)
如果你需要保留CSRF保护(比如接口同时支持浏览器表单提交),那你需要先从服务器获取CSRF令牌,再在POST请求中携带它。用requests可以这么实现:
import requests # 创建会话,保持cookie状态 session = requests.Session() # 先发送GET请求获取CSRF令牌(Django会在响应cookie中设置csrftoken) session.get('http://127.0.0.1:8080/') # 从会话的cookie中提取csrftoken csrf_token = session.cookies.get('csrftoken') # 发送POST请求,在请求头里带上X-CSRFToken response = session.post( 'http://127.0.0.1:8080/', headers={'X-CSRFToken': csrf_token} )
这样请求就能通过CSRF校验,正常进入你的视图方法。
另外补充一个小建议:你用的ListAPIView原本只支持GET请求,手动添加post方法虽然能工作,但更规范的做法是使用ListCreateAPIView(它默认支持GET列表查询和POST资源创建),不过这和你当前的403问题无关,仅供参考~
内容的提问来源于stack exchange,提问作者NoisyB
相关产品推荐
相关产品推荐

