Django Rest Framework在url中使用dot

Max*_*ulo 8 django django-rest-framework

使用DRF(Django Rest Framework)我的一个模型有一个IP地址作为主键.

class VTE(models.Model):
  ipaddr = models.CharField(primary_key=True, max_length=16)
  ...
Run Code Online (Sandbox Code Playgroud)

问题是PK包含点,并且当组装REST URL时,点被DRF解释为格式化选项,而不是主键的一部分.请参阅下面的错误和匹配的模式.

Request URL:    http://192.168.10.121/api/vtes/172.25.128.29/

Using the URLconf defined in vtfx.urls, Django tried these URL patterns, in this order:

...
^api/ ^$ [name='api-root']
^api/ ^\.(?P<format>[a-z0-9]+)$ [name='api-root']
^api/ ^vtes/$ [name='vte-list']
^api/ ^vtes/\.(?P<format>[a-z0-9]+)$ [name='vte-list']   <---- HERE
^api/ ^vtes/(?P<pk>[^/.]+)/$ [name='vte-detail']
^api/ ^vtes/(?P<pk>[^/.]+)/\.(?P<format>[a-z0-9]+)$ [name='vte-detail']
...
Run Code Online (Sandbox Code Playgroud)

使用点作为主键的一部分是错误的吗?如果不是,它与DRF路由器组装URL的方式不一致.

有DRF方法可以解决这个问题吗?

更新:上下文

api.py:
 class VTESerializer(serializers.ModelSerializer):
     class Meta:
         model = models.VTE

 class VTEViewSet(viewsets.ModelViewSet):
     queryset = models.VTE.objects.all()
     serializer_class = VTESerializer
     permission_classes = (permissions.AllowAny,)

urls.py:
 router = routers.DefaultRouter()
 router.register(r'vtes', api.VTEViewSet) 

 urlpatterns = patterns('',
     url(r'^api/', include(router.urls)),
     ...
 )
Run Code Online (Sandbox Code Playgroud)

Max*_*ulo 25

首先,可以.在网址中使用(点).见 Can.(句点)是URL的路径部分的一部分?

其次,问题不在format选项中,而是在用于捕获主键的Regex表达式中,该键不包括默认情况下的.(点)和/(斜杠).

(?P<pk>[^/.]+)  <--- This excludes the dots in the IP Address
Run Code Online (Sandbox Code Playgroud)

可以在ViewSet中覆盖正则表达式lookup_value_regex.这是解决问题的新ViewSet:

class VTEViewSet(viewsets.ModelViewSet):
    lookup_value_regex = '[0-9.]+'      #Just add this line & change your Regex if needed
    queryset = models.VTE.objects.all()
    serializer_class = VTESerializer
    permission_classes = (permissions.AllowAny,)
Run Code Online (Sandbox Code Playgroud)

  • 对于主键是可以包含点的字符串的任何人,正则表达式为lookup_value_regex = '[\w.]+' (2认同)