簡體   English   中英

Django Rest Framework,具有多個Viewset和Routers,用於同一對象

[英]Django Rest Framework with multiple Viewsets and Routers for the same object

我無法使用Django Rest Framework為同一個對象定義不同的視圖集。 以下是基於DRF快速入門重現問題的最小示例。 我使用的是python 3.5和最新的DRF。

教程/快速啟動/ 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": "user2@users.com"
        },
        {
            "url": "http://127.0.0.1:8000/users-minimal/1/",
            "username": "user1,
            "email": "user1@users.com"
        }
    ]
}

請注意,網址指向.../users-minimal/

最后說明:我的問題與問題有些類似,但建議的解決方案對我不起作用,也沒有說明為什么它應該首先起作用。

簡短回答:您必須將basename參數添加到您的users-minimal路由users-minimal

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

通常DRF genereates一個basename從你的自動queryset 這在DRF路由器文檔中進行了解釋,搜索了basename

你的兩個Viewset的使用相同的queryset ,因此最初有相同的basename 這導致您看到的問題,后來注冊的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]+)/?$>]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM