从update方法重定向至ViewSet列表视图时出现PUT方法不允许错误
DRF TemplateHTMLRenderer 重定向405问题解决
问题现象
基于Django REST Framework扩展开发,使用TemplateHTMLRenderer处理HTML视图,在SnippetViewSet的update方法中更新数据后,尝试通过HttpResponseRedirect重定向到snippet-list,但日志出现405错误:
[18/Sep/2023 19:08:46] "GET /snippets/5/ HTTP/1.1" 200 48984 [18/Sep/2023 19:08:50] "PUT /snippets/5/ HTTP/1.1" 302 0 Method Not Allowed: /snippets/ [18/Sep/2023 19:08:50] "PUT /snippets/ HTTP/1.1" 405 22
数据更新成功,但重定向后请求方法仍为PUT,而列表视图仅支持GET,导致方法不允许错误。
问题根源
页面开启了hx-boost="true",htmx在处理重定向时会**保留原请求的HTTP方法(PUT)**访问重定向目标URL,而ModelViewSet的list动作只接受GET请求,因此返回405。
解决方案
方案一:使用htmx专属重定向头
在update方法中返回带HX-Redirect头的响应,告诉htmx使用GET方法发起重定向请求:
from rest_framework import status def update(self, request, *args, **kwargs): snippet = get_object_or_404(Snippet, pk=kwargs.get('pk')) serializer = SnippetSerializer(snippet, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() # 构造带HX-Redirect头的响应 response = Response(status=status.HTTP_302_FOUND) response['HX-Redirect'] = reverse('snippet-list') return response
方案二:关闭表单的hx-boost功能
如果该表单不需要hx-boost增强,可以给表单添加hx-boost="false"属性,让浏览器以普通方式处理重定向(自动使用GET):
<form hx-boost="false"> {% csrf_token %} {% render_form serializer %} <button hx-put="{% url 'snippet-detail' pk=snippet.pk %}">Update</button> </form>
额外提示
代码中premission_classes存在拼写错误,正确应为permission_classes,修正后可避免权限验证相关问题。
内容的提问来源于stack exchange,提问作者henrikstroem
相关产品推荐
相关产品推荐

