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

使用PATCH方法时提示‘PATCH不被允许’的DRF问题求助

解决DRF中PATCH请求不允许及指定字段更新问题

嘿,我来帮你搞定这个DRF里的Method "PATCH" not allowed报错,同时实现仅更新first_name和password字段的需求!

一、先排查PATCH请求不允许的核心原因

ModelViewSet默认是支持PATCH请求(对应partial_update动作)的,出现这个错误大概率是路由配置不规范或者重写方法时的小疏漏:

1. 确保路由正确注册

如果你用DRF的路由器管理路由,要这样注册你的ViewSet:

from rest_framework.routers import DefaultRouter
from .views import UpdateUserSet

router = DefaultRouter()
# basename可根据你的模型业务调整
router.register(r'users', UpdateUserSet, basename='user')
urlpatterns = router.urls

如果是手动写路由,必须明确指定PATCH对应的视图动作:

from django.urls import path
from .views import UpdateUserSet

urlpatterns = [
    path('users/<int:pk>/', UpdateUserSet.as_view({
        'patch': 'partial_update',
        'put': 'update'
    }), name='user-detail'),
]

2. 检查视图的http_method_names配置

如果你的视图手动设置了允许的请求方法,一定要确保包含patch:

class UpdateUserSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    serializer_class = UserSerialize
    # 若有此配置,必须把'patch'加入列表
    http_method_names = ['get', 'patch', 'put']

二、实现仅更新first_name和password的逻辑

接下来修正视图和序列化器,既实现指定字段更新,又处理密码加密的特殊需求:

1. 修正序列化器(处理密码加密+字段限制)

密码不能直接存明文,要重写序列化器的update方法用set_password加密,同时限制可更新的字段:

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

class UserSerialize(serializers.ModelSerializer):
    class Meta:
        model = User
        # 只开放需要更新的两个字段
        fields = ['first_name', 'password']
        # 密码仅用于写入,不返回给前端
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def update(self, instance, validated_data):
        # 更新first_name(仅当请求中包含该字段时)
        if 'first_name' in validated_data:
            instance.first_name = validated_data['first_name']
        # 更新密码(仅当请求中包含该字段时)
        if 'password' in validated_data:
            instance.set_password(validated_data['password'])
        instance.save()
        return instance

2. 修正视图的partial_update方法

你之前的partial_update只是返回状态码,没有实际处理更新逻辑,改成这样(其实ModelViewSet默认已经实现了partial_update,若不需要额外逻辑,甚至可以直接删掉重写的方法):

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

class UpdateUserSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    serializer_class = UserSerialize
    # 必须指定queryset,或者重写get_queryset方法
    queryset = User.objects.all()

    def partial_update(self, request, pk=None):
        instance = self.get_object()
        # partial=True允许部分字段更新
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response(serializer.data, status=status.HTTP_200_OK)

三、测试验证

现在发送PATCH请求到/users/{user_id}/,请求体用JSON格式:

{
    "first_name": "新昵称",
    "password": "new_pass_123"
}

就能正确更新指定字段,再也不会出现方法不允许的错误啦!

内容的提问来源于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:43:42