DRF changes name or ignores "create" route

Viewed 83

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 uses request.user?

Many thanks

0 Answers
Related