Django创建Gallery图片字段时遇URL匹配与POST方法错误
Django Gallery创建功能的错误排查与解决
问题现象
开发Gallery图片字段创建功能时遇到两个问题:
- 访问
/gallery/create/时,报错:Field 'id' expected a number but got 'create' - Postman向该URL发起POST请求时,收到响应:
{ detail: "Method \"POST\" not allowed." }
相关代码
Gallery模型
class Gallery(models.Model): SUBTLEPBR = "subtle" AMULET = "amulet" F8THFULPBR = "f8thfulpbr" user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) screenshot_by = models.CharField(max_length=200, null=False, blank=False) image = WEBPField( verbose_name=('Image'), upload_to=image_folder, default="placeholder.png" ) PACKS = [ (SUBTLEPBR, 'SubtlePBR'), (AMULET, 'Amulet'), (F8THFULPBR, 'F8thfulPBR'), ] pack = models.CharField(max_length=10, choices=PACKS) def __str__(self): return "Screenshot by "+ self.screenshot_by + " | " + self.pack
创建视图
@api_view(["POST"]) @permission_classes([IsAdminUser]) def createGalleryImage(request): user = request.user gallery = Gallery.objects.create( user = user, screenshot_by = "John Doe", pack = Gallery.SUBTLEPBR, ) serializer = GallerySerializer(gallery, many=False) return Response(serializer.data)
原URL配置
urlpatterns = [ path('admin/users/login/', views.MyTokenObtainPairView.as_view(), name='token_obtain_pair'), path('', views.getRoutes, name='routes'), path("gallery/", views.GalleryImages, name="gallery"), path("gallery/<str:pk>/", views.getGalleryImage, name="gallery-image"), path("gallery/delete/<str:pk>/", views.deleteGalleryImage, name="gallery-delete"), path("gallery/create/", views.createGalleryImage, name="gallery-create"), path("updates/", views.PackUpdatesPage, name="updates"), path("faq/", views.FaqPage, name="faq"), path("subtle-roadmap/", views.SubtleRoadmapPage, name="subtle-roadmap"), path("amulet-roadmap/", views.AmuletRoadmapPage, name="amulet-roadmap"), path('admin/users/profile/', views.getUserProfile, name="user-profile") ]
错误原因
- URL路由顺序错误:Django路由按从上到下顺序匹配,
gallery/<str:pk>/路由在gallery/create/之前,导致请求/gallery/create/时,create被当作<str:pk>参数传入getGalleryImage视图。该视图期望pk是数字ID,无法解析字符串"create",因此抛出Field 'id' expected a number but got 'create'错误。 - 请求方法不匹配:由于请求被错误路由到
getGalleryImage视图(该视图大概率仅支持GET方法),POST请求被拒绝,返回Method "POST" not allowed。
解决方案
调整URL路由顺序
将具体操作路由(create、delete)放在通用的单对象路由(gallery/<str:pk>/)之前,确保Django优先匹配具体路由:
urlpatterns = [ path('admin/users/login/', views.MyTokenObtainPairView.as_view(), name='token_obtain_pair'), path('', views.getRoutes, name='routes'), path("gallery/", views.GalleryImages, name="gallery"), path("gallery/create/", views.createGalleryImage, name="gallery-create"), path("gallery/delete/<str:pk>/", views.deleteGalleryImage, name="gallery-delete"), path("gallery/<str:pk>/", views.getGalleryImage, name="gallery-image"), path("updates/", views.PackUpdatesPage, name="updates"), path("faq/", views.FaqPage, name="faq"), path("subtle-roadmap/", views.SubtleRoadmapPage, name="subtle-roadmap"), path("amulet-roadmap/", views.AmuletRoadmapPage, name="amulet-roadmap"), path('admin/users/profile/', views.getUserProfile, name="user-profile") ]
优化视图(可选)
如果需要动态接收请求参数(而非硬编码"John Doe"),可以修改视图使用序列化器处理请求数据,更符合RESTful规范:
from rest_framework import status @api_view(["POST"]) @permission_classes([IsAdminUser]) def createGalleryImage(request): serializer = GallerySerializer(data=request.data) if serializer.is_valid(): serializer.save(user=request.user) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
权限验证
Postman请求时需携带管理员用户的认证令牌(如JWT),确保通过IsAdminUser权限校验。
验证结果
调整路由后,/gallery/create/会正确路由到createGalleryImage视图,发送符合要求的POST请求后,将返回类似预期的JSON响应:
{ "id": 51, "screenshot_by": "Person", "image": "/placeholder.png", "pack": "subtle", "user": 1 }
内容的提问来源于stack exchange,提问作者Zoclhas
相关产品推荐
相关产品推荐

