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

使用Django Rest Framework遇PATCH方法不允许错误,求解决方案

解决DRF中"Method 'PATCH' not allowed"错误(仅更新指定字段)

Hey Denis, let's work through why you're hitting that "Method 'PATCH' not allowed" error and get your partial update for first_name and password working properly.

1. 问题根源分析

虽然ModelViewSet默认集成了UpdateModelMixin(它自带partial_update方法来支持PATCH请求),但你的自定义partial_update只是返回了201状态码,完全没有处理实际的更新逻辑,甚至没调用父类方法来完成请求的基础校验。另外,你的序列化器字段配置也可能存在问题(比如密码字段的处理),这也会间接导致请求被拦截。

2. 正确实现partial_update并限制更新字段

先修改视图类,让partial_update真正执行更新操作,同时严格限制只允许修改first_name和password:

from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.contrib.auth.models import User
from .serializers import UserSerialize

class UpdateUserSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    serializer_class = UserSerialize
    queryset = User.objects.all()  # 注意:ModelViewSet必须配置queryset,否则会导致路由生成异常

    def partial_update(self, request, pk=None):
        user = self.get_object()
        # 只保留允许更新的字段
        allowed_fields = ['first_name', 'password']
        update_data = {k: v for k, v in request.data.items() if k in allowed_fields}
        
        # 更新first_name
        if 'first_name' in update_data:
            user.first_name = update_data['first_name']
        
        # 更新密码(必须用set_password做哈希处理,不能直接赋值)
        if 'password' in update_data:
            user.set_password(update_data['password'])
        
        user.save()
        
        # 返回序列化后的用户数据
        serializer = self.get_serializer(user)
        return Response(serializer.data, status=status.HTTP_200_OK)

3. 修复序列化器的字段配置

你的UserSerialize需要正确处理密码字段(设置为仅写,避免返回明文密码),同时确保first_name支持修改:

from rest_framework import serializers
from django.contrib.auth.models import User

class UserSerialize(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)
    first_name = serializers.CharField(required=False)

    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'email', 'password']  # 按需包含字段,password仅用于写入

4. 最后检查两个关键点

  • 确认路由正确注册了ModelViewSet,比如用router.register(r'users', UpdateUserSet),DRF会自动生成包含PATCH在内的所有标准路由。
  • 确保请求发送到详情路由(比如/users/{pk}/),PATCH是针对单个资源的操作,不能发送到列表路由。

这样调整后,你的PATCH请求就能正常执行,并且只会更新你指定的first_name和password字段了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:42:08