Django REST Framework中UpdateAPIView接收GET请求提示不允许问题求助
问题:配置允许GET请求的权限类后,仍收到"GET method is not allowed"提示
我为视图类配置了允许GET请求的权限类,但发送GET请求时却返回"GET method is not allowed"错误。
视图类代码(views.py)
class WomenAPIList(generics.ListCreateAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAuthenticatedOrReadOnly, ) class WomenAPIUpdate(generics.UpdateAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAuthenticated, ) # authentication_classes = (TokenAuthentication, ) class WomenAPIDestroy(generics.RetrieveDestroyAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAdminOrReadOnly, )
其中WomenAPIUpdate的单独代码:
class WomenAPIUpdate(generics.UpdateAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAuthenticated, ) # authentication_classes = (TokenAuthentication, )
URL配置(urls.py)
urlpatterns = [ path('admin/', admin.site.urls), path('api/v1/drf-auth/', include('rest_framework.urls')), path('api/v1/women/', WomenAPIList.as_view()), path('api/v1/women/<int:pk>/', WomenAPIUpdate.as_view()), path('api/v1/womendelete/<int:pk>/', WomenAPIDestroy.as_view()), path('api/v1/auth/', include('djoser.urls')), re_path(r'^auth/', include('djoser.urls.authtoken')), path('api/v1/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('api/v1/token/verify/', TokenVerifyView.as_view(), name='token_verify'), ]
对应WomenAPIUpdate的URL规则:
path('api/v1/women/<int:pk>/', WomenAPIUpdate.as_view()),
模型代码(models.py)
class Women(models.Model): title = models.CharField(max_length=255) content = models.TextField(blank=True) time_create = models.DateTimeField(auto_now_add=True) time_update = models.DateTimeField(auto_now=True) is_published = models.BooleanField(default=True) cat_id = models.ForeignKey('Category', on_delete=models.PROTECT, null=True) car_id = models.BooleanField(default=True) user = models.ForeignKey(User, verbose_name='Пользователь', on_delete=models.CASCADE) def __str__(self): return self.title class Category(models.Model): name = models.CharField(max_length=100, db_index=True) def __str__(self): return self.name
自定义权限类尝试
我尝试自定义允许SAFE_METHODS(包含GET)的权限类并应用到WomenAPIUpdate,但无效:
class IsAdminOrReadOnly(BasePermission): def has_permission(self, request, view): if request.method in permissions.SAFE_METHODS: return True return bool(request.user and request.user.is_staff) class IsOwnerOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True return obj.user == request.user
SAFE_METHODS的定义:
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
认证配置(settings.py)
该功能原本正常,直到我配置了以下认证设置后出现问题:
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ] }
解决方案
问题核心是视图类本身不支持GET方法,UpdateAPIView默认仅允许PUT、PATCH请求,和权限配置无关。解决方式有两种:
- 替换视图类为
RetrieveUpdateAPIView,该类同时支持GET(单条数据查询)、PUT、PATCH方法:
class WomenAPIUpdate(generics.RetrieveUpdateAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAuthenticated, )
- 若需保留
UpdateAPIView,可通过http_method_names手动添加允许的GET方法:
class WomenAPIUpdate(generics.UpdateAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAuthenticated, ) http_method_names = ['get', 'put', 'patch'] # 显式添加GET方法
内容的提问来源于stack exchange,提问作者imartov
相关产品推荐
相关产品推荐

