Django API传入邮箱地址请求返回404错误的问题求助
解决Django ViewSet中含点的用户名/邮箱URL 404问题
你遇到的问题确实是URL里的点导致的——Django路由默认会把最后一个点后面的内容当成格式后缀(比如.json),请求/api/otps/javi@gmail.com/时,系统会把javi@gmail当作pk参数,.com被当成格式后缀,所以你的get_otp方法拿到的不是完整邮箱,自然查不到用户返回404。
给你三个可行的解决办法:
方法一:禁用ViewSet的格式后缀支持
直接在你的OTPSViewSet类里加一行配置,彻底关闭格式后缀解析:
class OTPSViewSet(viewsets.ViewSet, mixins.RetrieveModelMixin, mixins.CreateModelMixin): throttle_classes = [OncePerDayUserThrottle] authentication_classes = [] permission_classes = [] # 新增这行,禁用格式后缀 format_kwarg = None # 原有方法...
或者用DefaultRouter注册路由时,加上format=None参数:
router = DefaultRouter() router.register(r'otps', OTPSViewSet, basename='otp', format=None)
方法二:自定义URL正则,允许pk包含点
如果是手动写URL配置(不用Router),可以用正则表达式明确让pk匹配包含点的字符串:
from django.urls import re_path, path # 方法1:用path的str类型(Django 2.0+支持,str会匹配除了/之外的所有字符) urlpatterns = [ path('api/otps/<str:pk>/', OTPSViewSet.as_view({'get': 'retrieve'})), ] # 方法2:用re_path更精确控制 urlpatterns = [ re_path(r'^api/otps/(?P<pk>[^/]+)/$', OTPSViewSet.as_view({'get': 'retrieve'})), ]
[^/]+表示匹配任意非斜杠字符,自然包含点,这样就能完整捕获javi@gmail.com作为pk参数。
方法三:请求时显式指定格式后缀(客户端配合)
如果不想改服务端配置,可以让请求URL加上格式后缀,比如:
GET /api/otps/javi@gmail.com/.json HTTP/1.1
这样Django会把javi@gmail.com当作完整的pk,.json作为格式后缀,也能正常命中路由。不过这个方法需要客户端调整请求,不如前两种灵活。
改完之后再测试/api/otps/javi@gmail.com/,就能正确拿到完整的邮箱参数,返回200状态码了。
内容的提问来源于stack exchange,提问作者Javier Crespo
相关产品推荐
相关产品推荐

