Reputation: 7202
I have one model for which I've defined two different 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
is being used by a couple GenericViews
in one Django app (i.e. its own urls.py), and FooSerializer2
by a ModelViewSet
in another Django app. I have the ModelViewSet
registered in a DefaultRouter
along with a few other viewsets:
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
That router's auto-generated api root displays the endpoint for the GenericView
of FooSerializer1
(foo1-list
), instead of foo2/
. If I manually GET foo2/
, the results show Foo
serialized according to FooSerializer2
(which is correct), however the URL for each result again displays the foo1
detail view.
I tried setting get_serializer
in FooViewSet2
, but that didn't work. How do I get the api-root and FooSerializer2
results to display the URLs corresponding to FooViewset2
?
Upvotes: 6
Views: 2648
Reputation: 7202
DRF fortunately allows the flexibility to support this scenario through setting a few parameters.
First, I set the basename
parameter on the router entry:
router.register(r'foo2', views.Foo2ViewSet, 'foo2')
Next, I set the view_name
in the HyperlinkedModelSerializers
in order to not default to foo-detail
as mentioned 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',
)
...
Upvotes: 10