[英]Django Rest Framework with multiple Viewsets and Routers for the same object
I am having trouble defining different view sets for the same object using Django Rest Framework. 我无法使用Django Rest Framework为同一个对象定义不同的视图集。 Following is a minimal example to reproduce the issue, based on DRF Quickstart.
以下是基于DRF快速入门重现问题的最小示例。 I am using python 3.5 and the latest DRF.
我使用的是python 3.5和最新的DRF。
tutorial/quickstart/serializers.py 教程/快速启动/ 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')
tutorial/quickstart/views.py 教程/快速启动/ 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
tutorial/urls.py 教程/ 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))
]
When running the server and GETting the root, you end up with: 运行服务器并获取根目录时,最终得到:
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/"
}
Note both users
and users-minimal
point to .../users-minimal/
. 注意
users
和users-minimal
指向.../users-minimal/
。
Also, when accessing http://HOST:PORT/users/
you get: 此外,当访问
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"
}
]
}
Note the urls point to .../users-minimal/
. 请注意,网址指向
.../users-minimal/
。
Final note: my question is somewhat similar to this one , but the suggested solution did not work for me, nor did it suggest why it should work in the first place. 最后说明:我的问题与此问题有些类似,但建议的解决方案对我不起作用,也没有说明为什么它应该首先起作用。
Short answer: You have to add the basename
parameter to your route to users-minimal
: 简短回答:您必须将
basename
参数添加到您的users-minimal
路由users-minimal
:
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'users-minimal', UserMinimalViewSet, basename='usersminimal')
Normally DRF genereates a basename
automatically from your queryset
. 通常DRF genereates一个
basename
从你的自动queryset
。 This is explained in the DRF routers docs , search for basename
. 这在DRF路由器文档中进行了解释,搜索了
basename
。
Your two Viewset
s use the same queryset
so the have initially the same basename
. 你的两个
Viewset
的使用相同的queryset
,因此最初有相同的basename
。 That leads to the problems which you have seen, that the later registered ViewSet
will overwrite the routes from the former registered ViewSet
. 这导致您看到的问题,后来注册的
ViewSet
将覆盖以前注册的ViewSet
的路由。 You can see this in action when you change the order of the router.register
in your example. 在更改示例中
router.register
的顺序时,您可以看到此操作。
You can see the base names of your routes when you test the code directly in the shell: 在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.