I have a ViewSet using Django REST Framework that has both standard and custom routes. The serializer for each route is different.
Example:
class UserViewSet(ViewSet):
model = User
serializer_class = UserSerializer
@decorators.detail_route(methods=['put'])
def change_password(self, request, pk, *args, **kwargs):
serializer = UserChangePasswordSerializer(data=request.data)
...
@decorators.detail_route(methods=['put'])
def update_prefs(self, request, *args, **kwargs):
serializer = UserPreferencesSerializer(data=request.data)
...
I have everything working such that I can perform standard get, post, put, delete actions on the User object and the two extra routes work. However, I can't figure out how to make the HTML forms for the custom routes display when using the BrowsableAPIRenderer
. It would be very handy for developers to be able to see forms demonstrating the fields that are expected on the above put methods, for example.
I tried adding get methods for the two routes, but this is non-sensical for the first one. Regardless, I don't see the right serializer displayed when I go to the URL for the route, I see the serializer specified in serializer_class
.
About the only thing I haven't tried is overriding get_serializer_class()
because this involves putting knowledge of every serializer for every route in a single place rather than being able to specify the serializer within the route method itself... is this the way I should be trying to get the desired effect?
It turns out I need to not use
serializer_class
and instead overrideget_serializer_class
. Since this takes an action, I canif..elif..else
on that to return the right serializer. Clever use of a dictionary then makes this easy:This will return the
UserSerializer
for all actions unless I specify a different serializer in theserializers
dictionary. Easier than I thought it would be.