使用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
相关产品推荐
相关产品推荐

