Routers work with a ViewSet
and aren't designed for normal views, but that doesn't mean that you cannot use them with a normal view. Normally they are used with models (and a ModelViewSet
), but they can be used without them using the GenericViewSet
(if you would normally use a GenericAPIView
) and ViewSet
(if you would just use an APIView
).
For a list view, the request methods are mapped to ViewSet
methods like this
GET
-> list(self, request, format=None)
POST
- > create(self, request, format=None)
For detail views (with a primary key in the url), the request methods use the following map
GET
-> retrieve(self, request, pk, format=None)
PUT
-> update(self, request, pk, format=None)
PATCH
-> partial_update(self, request, pk, format=None)
DELETE
-> destroy(self, request, pk, format=None)
So if you want to use any of these request methods with your view on your router, you need to override the correct view method (so list()
instead of get()
).
Now, specifically in your case you would have normally use an APIView
that looked like
class UpdateTimeView(APIView):
def get(self, request, format=None):
latest_publish = Publish.objects.latest('created_time')
latest_meeting = Meeting.objects.latest('created_time')
latest_training = Training.objects.latest('created_time')
latest_exhibiting = Exhibiting.objects.latest('created_time')
return Response({
"publish_updatetime": latest_publish.created_time,
"meeting_updatetime": latest_meeting.created_time,
"training_updatetime": latest_training.created_time,
"exhibiting_updatetime": latest_exhibiting.created_time,
})
The comparable ViewSet
would be
class UpdateTimeViewSet(ViewSet):
def list(self, request, format=None):
latest_publish = Publish.objects.latest('created_time')
latest_meeting = Meeting.objects.latest('created_time')
latest_training = Training.objects.latest('created_time')
latest_exhibiting = Exhibiting.objects.latest('created_time')
return Response({
"publish_updatetime": latest_publish.created_time,
"meeting_updatetime": latest_meeting.created_time,
"training_updatetime": latest_training.created_time,
"exhibiting_updatetime": latest_exhibiting.created_time,
})
Notice the two required changes: APIView
-> ViewSet
and get
-> list
. I also updated the name to indicate that it was more than just a normal view (as a ViewSet
cannot be initialized the same way), but that's not required.
So with this new view, you can just register it in the router the same way as any other. You need a base_name
here so the url names can be generated (normally this would pull from the queryset).
router.register(r'updatetime', views.UpdateTimeViewSet, base_name='updatetime')
So now the updatetime
endpoint will be made available in the API root and you can get the latest times by just calling the endpoint (a simple GET request).