2016-11-23 47 views
3

我無法爲使用Django Rest Framework的同一對象定義不同的視圖集。以下是基於DRF快速入門重現問題的最小示例。我正在使用python 3.5和最新的DRF。具有多個Viewset和路由器的Django Rest Framework用於同一對象

教程/快速啓動/ serializers.py

from django.contrib.auth.models import User 
from rest_framework import serializers 


class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('url', 'username', 'email') 

class UserMinimalSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('url', 'username') 

教程/快速啓動/ views.py

from django.contrib.auth.models import User 
from rest_framework import viewsets 
from tutorial.quickstart.serializers import UserSerializer, UserMinimalSerializer 

class UserViewSet(viewsets.ModelViewSet): 
    queryset = User.objects.all().order_by('-date_joined') 
    serializer_class = UserSerializer 


class UserMinimalViewSet(viewsets.ModelViewSet): 
    queryset = User.objects.all().order_by('-date_joined') 
    serializer_class = UserMinimalSerializer 

教程/ urls.py

from django.conf.urls import url, include 
from rest_framework import routers 
from tutorial.quickstart import views 

router = routers.DefaultRouter() 
router.register(r'users', views.UserViewSet) 
router.register(r'users-minimal', views.UserMinimalViewSet) 

urlpatterns = [ 
    url(r'^', include(router.urls)) 
] 

當運行在服務器和入門的根,你結束了:

HTTP 200 OK 
Allow: GET, HEAD, OPTIONS 
Content-Type: application/json 
Vary: Accept 

{ 
    "users": "http://127.0.0.1:8000/users-minimal/", 
    "users-minimal": "http://127.0.0.1:8000/users-minimal/" 
} 

注意兩個usersusers-minimal.../users-minimal/

此外,訪問http://HOST:PORT/users/當你:

HTTP 200 OK 
Allow: GET, POST, OPTIONS 
Content-Type: application/json 
Vary: Accept 

{ 
    "count": 2, 
    "next": null, 
    "previous": null, 
    "results": [ 
     { 
      "url": "http://127.0.0.1:8000/users-minimal/2/", 
      "username": "user2", 
      "email": "[email protected]" 
     }, 
     { 
      "url": "http://127.0.0.1:8000/users-minimal/1/", 
      "username": "user1, 
      "email": "[email protected]" 
     } 
    ] 
} 

注意的URL指向.../users-minimal/

最後說明:我的問題有點類似於this one,但是建議的解決方案對我來說並不適用,也沒有說明它爲什麼應該起作用。

回答

4

簡短的回答:你必須向base_name參數添加到您的路線users-minimal

router = routers.DefaultRouter() 
router.register(r'users', UserViewSet) 
router.register(r'users-minimal', UserMinimalViewSet, base_name='usersminimal') 

通常DRF從您的查詢集自動genereates一個base_name。 這在「base_name」下解釋:www.django-rest-framework.org/api-guide/routers/

您的兩個viewsets使用相同的查詢集,所以最初具有相同的base_name。這導致了你所看到的問題,即後來註冊的ViewSet將覆蓋來自先前註冊的ViewSet的路由。 在您的示例中更改router.register的順序時,您可以看到這一點。

你可以看到你的路由的基本名稱,當你直接在shell測試代碼:

from rest_framework import routers 
from tutorial.quickstart import views 

router = routers.DefaultRouter() 
router.register(r'users', views.UserViewSet) 
router.register(r'users-minimal', views.UserMinimalViewSet) 


> routers.urls 
[<RegexURLPattern user-list ^minimal/$>, 
<RegexURLPattern user-list ^minimal\.(?P<format>[a-z0-9]+)/?$>, 
<RegexURLPattern user-detail ^minimal/(?P<pk>[^/.]+)/$>, 
<RegexURLPattern user-detail ^minimal/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, 
<RegexURLPattern user-list ^users/$>, 
<RegexURLPattern user-list ^users\.(?P<format>[a-z0-9]+)/?$>, 
<RegexURLPattern user-detail ^users/(?P<pk>[^/.]+)/$>, 
<RegexURLPattern user-detail ^users/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, 
<RegexURLPattern api-root ^$>, 
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>]