Django REST框架:针对同一模型的两个不同的ModelSerializer

Nei*_*eil 5 django django-rest-framework

我有一个模型,我已经定义了两个不同的HyperlinkedModelSerializers:

class Foo(models.Model):
    ...

class FooSerializer1(serializers.HyperlinkedModelSerializer):
    ...

    class Meta:
        model = Foo
        fields = ('url', 'id', ...)
        lookup_field= 'pk'

# A second view of the same model for another API use-case
class FooSerializer2(serializers.HyperlinkedModelSerializer):
    ...

    class Meta:
        model = Foo
        fields = ('url', 'id', ...)
        lookup_field= 'pk'
Run Code Online (Sandbox Code Playgroud)

FooSerializer1正在使用的一对夫妇GenericViews在一个Django应用程序(即,其自己的urls.py),并FooSerializer2通过一个ModelViewSet在另一个Django应用程序.我已经ModelViewSet注册了一些DefaultRouter以及其他一些视图集:

urlpatterns = patterns('',
    url(r'^$', 'myapp.views.api_root'),
    url(r'^foo1/$', views.FooList1.as_view(), name='foo1-list'),
    ...
)

urlpatterns = format_suffix_patterns(urlpatterns)

...

class FooViewSet2(viewsets.ReadOnlyModelViewSet):
    queryset = Foo.objects.all()
    serializer_class = FooSerializer2
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get_queryset(self):
        ...

router = routers.DefaultRouter()
...
router.register(r'foo2', views.FooViewSet2)
...
urlpatterns = router.urls
Run Code Online (Sandbox Code Playgroud)

该路由器的自动生成的api根显示GenericViewof FooSerializer1(foo1-list)的端点,而不是foo2/.如果我手动GET foo2/,结果显示Foo根据FooSerializer2(这是正确的)序列化,但每个结果的URL再次显示foo1详细信息视图.

我尝试过get_serializer进入FooViewSet2,但是没有用.如何获取api-root和FooSerializer2结果以显示对应的URL FooViewset2

Nei*_*eil 9

幸运的是,DRF允许通过设置一些参数来灵活地支持这种情况.

首先,我basename在路由器条目上设置参数:

router.register(r'foo2', views.Foo2ViewSet, 'foo2')
Run Code Online (Sandbox Code Playgroud)

接下来,我设置view_nameHyperlinkedModelSerializers,为了不默认foo-detail在文档中提到:

class FooSerializer1(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='foo1-detail',
    )
    ...

urlpatterns = patterns('',
    url(r'^$', 'myapp.views.api_root'),
    url(r'^foo1/$', views.Foo1List.as_view(), name='foo1-list'),
    url(r'^foo1/(?P<pk>[0-9]+)/$', views.FooDetail1.as_view(), name='foo1-detail'),

    ...

class FooSerializer2(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='foo2-detail',
    )
    ...
Run Code Online (Sandbox Code Playgroud)