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
?
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
Django REST framework is built on Django, which is a synchronous framework for web applications.
Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
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',
)
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With