I'm new to DRF's "viewsets", but I've inherited some problematic code, and am having trouble figuring out what's going on. I have stripped down the code below to isolate the behavior I don't understand.
In my urls.py
I have
from my_app.api import CurrentUserViewSet,
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register("me", CurrentUserViewSet, basename="api-me")
print(router.urls)
Note the diagnostic print
statement at the end.
The CurrentUserViewSet
is defined as:
from rest_framework import viewsets
from django.views.generic import View
class CurrentUserViewSet(viewsets.ViewSetMixin, View):
def create(self, request):
"""Update current user."""
instance = request.user
...
@action(detail=False, methods=["post"])
def some_other_route(self, request):
...
When I start a runserver instance that uses the above, it hits my print
statement in "urls.py" and displays this:
[
<URLPattern '^me/$' [name='api-me-list']>,
<URLPattern '^me\.(?P<format>[a-z0-9]+)/?$' [name='api-me-list']>,
<URLPattern '^me/some_other_route/$' [name='api-me-some-other-route']>,
<URLPattern '^me/some_other_route\.(?P<format>[a-z0-9]+)/?$' [name='api-me-some-other-route']>...
]
So it looks like the name of my create
route is being changed to list
. I don't know how or why this is happening. Interestingly, if I define an addtional route that is actually named "list", the "create" method still does not appear in the URLs created by the router. It seems to be totally ignored.
As I mentioned, I inherited this code. I think that even though the original author named this route "create", he was actually trying to update the currently authenticated user (as implied by the docstring). I think he put his custom code in a method called "create" because he wanted to get the user from request.user
and not retrieve it from a pk in a signature like def update(self, request, pk=None)
.
But this doesn't seem to work because execution will never enter that create
method. At least, I've never seen it happen.
So my questions are:
- Would the code above ever have worked, maybe in some earlier version of DRF?
- If I name a route "create", why/how does it get changed to "list"?
- If I add a route that is actually named "list", why is the "create" route ignored by
DefaultRouter
? - What is a better way to update the currently authenticated user that does not take a
pk
parameter, but just usesrequest.user
?
Many thanks