2015-01-15 30 views
7

Utilizzando DRF (Django Rest Framework) uno dei miei modelli ha un indirizzo IP come chiave primaria.Django Rest Framework usando il punto nell'URL

class VTE(models.Model): 
    ipaddr = models.CharField(primary_key=True, max_length=16) 
    ... 

Il problema è che il PK contiene punti, e quando l'URL REST è assemblato i punti vengono interpretati come opzioni di formattazione da DRF invece come parte della chiave primaria. Vedi l'errore di seguito e i modelli corrispondenti.

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'] 
... 

è sbagliato usare i puntini come parte della chiave primaria? In caso contrario, è incompatibile con il modo in cui il router DRF raggruppa gli URL.

C'è un modo DRF per risolvere quello?

UPDATE: contesto

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)), 
    ... 
) 
+1

come un suggerimento per le persone che vedono questo errore dopo un aggiornamento da 2.3.x a 2,4: Sembra che prima di 2.4, i punti sono stati inclusi nel lookup_value_regex di default, a condizione che trailing_slash era impostato su True. – jgiralt

risposta

16

In primo luogo, è ok per utilizzare il . (dot) negli URL. Vedere Can . (period) be part of the path part of an URL?

In secondo luogo, il problema non era l'opzione format ma nell'espressione Regex usata per catturare la chiave primaria, che esclude il . (punto) e / (slash) per impostazione predefinita.

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

L'espressione regolare può essere overrided nel ViewSet con lookup_value_regex. Questo è il nuovo ViewSet che risolve il problema:

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,) 
+1

ti benedico, pensavo che sarei diventato pazzo ^^ –

Problemi correlati