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

时间:2014-06-22 12:36:16

标签: 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'

FooSerializer1正在一个Django应用中使用GenericViews(即自己的urls.py),而FooSerializer2则在另一个Django应用中使用ModelViewSet。我在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

该路由器的自动生成的api根显示GenericView FooSerializer1foo1-list)的端点,而不是foo2/。如果我手动获取foo2/,则结果显示Foo已根据FooSerializer2序列化(这是正确的),但每个结果的网址会再次显示foo1详细信息视图。< / p>

我尝试在get_serializer中设置FooViewSet2,但这不起作用。如何获取api-root和FooSerializer2结果以显示与FooViewset2对应的网址?

1 个答案:

答案 0 :(得分:9)

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

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

router.register(r'foo2', views.Foo2ViewSet, 'foo2')

接下来,我在view_name中设置了HyperlinkedModelSerializers,以便默认为foo-detailmentioned in the docs

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',
    )
    ...