8

I read about the viewsets in django, but haven't fully understood everything..

When using a viewset in django, for example -

class SnippetViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.

    Additionally we also provide an extra `highlight` action.
    """
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    @detail_route(renderer_classes=[renderers.StaticHTMLRenderer])
    def highlight(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

and Routing is like this

router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)

In the comments in the View they say - "This viewset automatically provides list, create, retrieve,update and destroy actions."

EDIT:::

 @detail_route(methods=['post'])
    def register(request):
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
            user = User.objects.create_user(
                username = serializer.init_data['username'],
                password = serializer.init_data['password'],
            )

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  • How do I access each one of those methods? and How do I access the highlight method?
  • The url registered in the router is /snippets. Do I do snippets/create? or snippets/delete?
  • What does the ModelViewSet actually does to the url structure?
1

1 Answer 1

7

You access those actions by specifying the corresponding HTTP method, which is a core idea in REST. Namely, using the HTTP methods to do what their name implies.

  • GET /snippets/ - list the snippet objects
  • POST /snippets/ with POST data - create a new object
  • PATCH /snippets/ with data - create a new object
  • GET /snippets/42 - retrieve object with a primary key of 42
  • PUT/PATCH /snippets/42 - update object with the primary key of 42
  • DELETE /snippets/42 - delete object with the primary key of 42

To see all the generated and inferred URL regexes, put Django in debug mode and issue a request to an invalid URL. It will print out something like:

Using the URLconf defined in my_app.urls, Django tried these URL patterns, in this order:
^ ^$ [name='api-root']
^ ^\.(?P<format>[a-z0-9]+)$ [name='api-root']
^ ^AltEmail/$ [name='altemail-list']
^ ^AltEmail/\.(?P<format>[a-z0-9]+)$ [name='altemail-list']
^ ^AltEmail/(?P<pk>[^/.]+)/$ [name='altemail-detail']
^ ^AltEmail/(?P<pk>[^/.]+)/\.(?P<format>[a-z0-9]+)$ [name='altemail-detail']
[...]
Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your answer. so lets say I have a UserViewSet(viewsets.ReadOnlyModelViewSet), so I'll have only the GET /users (list) and GET /users/42 (User number 42)?
Pretty much. One more tiny detail. You can add a suffix to override the content-type of your request header. e.g. /users/.json or /users/42/.json. You'll see that in regexes as (?P<format>[a-z0-9]+).
got it. one more thing, if I add a detail_route decorator (see my edited question), to access this method will be users/register/?
I haven't used that specific feature, but per this snippet ^users/{pk}/set_password/$, perhaps you can only access it via the primary key? Anyways, I don't know. Best to just try it out :-D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.