Update 6-viewsets-and-routers.md (#8590)

* Update 6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

* Update docs/tutorial/6-viewsets-and-routers.md

Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
This commit is contained in:
Géry Ogam 2022-11-22 09:39:26 +01:00 committed by GitHub
parent 8175f05c89
commit fd7d3a7b92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,10 +10,11 @@ A `ViewSet` class is only bound to a set of method handlers at the last moment,
Let's take our current set of views, and refactor them into view sets. Let's take our current set of views, and refactor them into view sets.
First of all let's refactor our `UserList` and `UserDetail` views into a single `UserViewSet`. We can remove the two views, and replace them with a single class: First of all let's refactor our `UserList` and `UserDetail` classes into a single `UserViewSet` class. We can remove the two view classes, and replace them with a single ViewSet class:
from rest_framework import viewsets from rest_framework import viewsets
class UserViewSet(viewsets.ReadOnlyModelViewSet): class UserViewSet(viewsets.ReadOnlyModelViewSet):
""" """
This viewset automatically provides `list` and `retrieve` actions. This viewset automatically provides `list` and `retrieve` actions.
@ -25,13 +26,14 @@ Here we've used the `ReadOnlyModelViewSet` class to automatically provide the de
Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighlight` view classes. We can remove the three views, and again replace them with a single class. Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighlight` view classes. We can remove the three views, and again replace them with a single class.
from rest_framework import permissions
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import permissions
class SnippetViewSet(viewsets.ModelViewSet): class SnippetViewSet(viewsets.ModelViewSet):
""" """
This viewset automatically provides `list`, `create`, `retrieve`, This ViewSet automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions. `update` and `destroy` actions.
Additionally we also provide an extra `highlight` action. Additionally we also provide an extra `highlight` action.
@ -64,9 +66,10 @@ To see what's going on under the hood let's first explicitly create a set of vie
In the `snippets/urls.py` file we bind our `ViewSet` classes into a set of concrete views. In the `snippets/urls.py` file we bind our `ViewSet` classes into a set of concrete views.
from snippets.views import SnippetViewSet, UserViewSet, api_root
from rest_framework import renderers from rest_framework import renderers
from snippets.views import api_root, SnippetViewSet, UserViewSet
snippet_list = SnippetViewSet.as_view({ snippet_list = SnippetViewSet.as_view({
'get': 'list', 'get': 'list',
'post': 'create' 'post': 'create'
@ -87,7 +90,7 @@ In the `snippets/urls.py` file we bind our `ViewSet` classes into a set of concr
'get': 'retrieve' 'get': 'retrieve'
}) })
Notice how we're creating multiple views from each `ViewSet` class, by binding the http methods to the required action for each view. Notice how we're creating multiple views from each `ViewSet` class, by binding the HTTP methods to the required action for each view.
Now that we've bound our resources into concrete views, we can register the views with the URL conf as usual. Now that we've bound our resources into concrete views, we can register the views with the URL conf as usual.
@ -108,9 +111,10 @@ Here's our re-wired `snippets/urls.py` file.
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from snippets import views from snippets import views
# Create a router and register our viewsets with it. # Create a router and register our ViewSets with it.
router = DefaultRouter() router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet, basename='snippet') router.register(r'snippets', views.SnippetViewSet, basename='snippet')
router.register(r'users', views.UserViewSet, basename='user') router.register(r'users', views.UserViewSet, basename='user')
@ -120,12 +124,12 @@ Here's our re-wired `snippets/urls.py` file.
path('', include(router.urls)), path('', include(router.urls)),
] ]
Registering the viewsets with the router is similar to providing a urlpattern. We include two arguments - the URL prefix for the views, and the viewset itself. Registering the ViewSets with the router is similar to providing a urlpattern. We include two arguments - the URL prefix for the views, and the view set itself.
The `DefaultRouter` class we're using also automatically creates the API root view for us, so we can now delete the `api_root` method from our `views` module. The `DefaultRouter` class we're using also automatically creates the API root view for us, so we can now delete the `api_root` function from our `views` module.
## Trade-offs between views vs viewsets ## Trade-offs between views vs ViewSets
Using viewsets can be a really useful abstraction. It helps ensure that URL conventions will be consistent across your API, minimizes the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf. Using ViewSets can be a really useful abstraction. It helps ensure that URL conventions will be consistent across your API, minimizes the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf.
That doesn't mean it's always the right approach to take. There's a similar set of trade-offs to consider as when using class-based views instead of function based views. Using viewsets is less explicit than building your views individually. That doesn't mean it's always the right approach to take. There's a similar set of trade-offs to consider as when using class-based views instead of function-based views. Using ViewSets is less explicit than building your API views individually.