具有多个视图集的Django Rest Framework路由器

时间:2015-05-29 15:54:38

标签: django django-rest-framework

我正在尝试使用DRF 3.1创建API。我首先使用ModelViewSet创建管理功能并使用DefaultRouter注册这些功能。这非常有效,默认API根视图在浏览器中查看时生成了相应的链接。然后,我使用ReadOnlyModelViewSet为标准用户创建了更多受限制的视图集,当我尝试使用路由器注册这些受限制的视图集时出现问题,因为ReadOnlyModelViewSets似乎覆盖了API根视图上的链接。生成的URL在键入浏览器时似乎有效,但API根视图上的链接不是我预期的

serializers.py

class AdminUnitSerializer(serializers.HyperlinkedModelSerializer):
'''
model serializer for admin users containing all fields

'''

url = HyperlinkedIdentityField(view_name='unit-detail')

class Meta:
    model = Unit
    fields = ('url', 'id', 'name', 'symbol', 'converters_from', 'converters_to')

class UserUnitSerializer(serializers.HyperlinkedModelSerializer):
'''
model serializer for standard users containing restricted set of fields

'''

url = HyperlinkedIdentityField(view_name='unit-detail')

class Meta:
    model = Unit
    fields = ('url', 'id', 'name', 'symbol')

views.py

class AdminUnitViewSet(viewsets.ModelViewSet):
'''
simple viewset providing CRUD operations on unit objects

'''

queryset = models.Unit.objects.all()
serializer_class = serializers.AdminUnitSerializer
permission_classes = (permissions.IsAdminUser,)

class UserUnitViewSet(viewsets.ReadOnlyModelViewSet):
'''
read only view set providing list and detail views for unit objects

'''

queryset =  models.Unit.objects.all()
serializer_class = serializers.UserUnitSerializer
permission_classes(permissions.IsAuthenticated,)

urls.py

router.register(r'manangeunits', views.AdminUnitViewSet)
router.register(r'readunits', views.UserUnitViewSet)

urlpatterns = [
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^', include(router.urls))
]

这会生成一个默认的API根视图,如下所示

{
"manangeunits": "http://localhost:8000/readunits/",
"readunits": "http://localhost:8000/readunits/",
}

而我正在寻找的是这个

{
"manangeunits": "htt://localhost:8000/manageunits/",
"readunits": "htt://localhost:8000/readunits/",
}

url'http:// localhost:8000 / manageunits /'在地址输入浏览器时有效且可访问,它只是没有出现在API根视图中

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:10)

我有同样的问题,幸运的是找到了解决方案。

将您的urls.py扩展如下:

router.register(r'manangeunits', views.AdminUnitViewSet, base_name='manangeunits')
router.register(r'readunits', views.UserUnitViewSet, base_name='readunits')

我不知道这背后的魔力,但它对我有用:)

答案 1 :(得分:3)

Dario Behringer的回答是正确的。但这不仅仅是魔术。

重要的部分是添加明确的base_name。通常,DRF会自动从您的查询集生成base_name。这将在" base_name":www.django-rest-framework.org/api-guide/routers/下解释。 AdminUnitViewSetUserUnitViewSet的查询集内部相同。

这会导致以后注册的ViewSet在未注册明确的新ViewSet时覆盖以前注册的base_name

base_name负责在Django中创建命名URL。如果有多个具有相同名称的命名URL,Django基本上只会考虑最新定义的:https://docs.djangoproject.com/en/1.10/topics/http/urls/#naming-url-patterns

这与问题Django Rest Framework with multiple Viewsets and Routers for the same object

中解释的问题基本相同