Class-based Views
Keep our code DRY
(Don’t repeat yourself).
One of the big wins of using class-based views is that it allows us to easily compose reusable bits
of behaviour.
# Types
* APIview
* Mixins
* Generic
APIview
- It looks pretty similar to the previous fxn based view,
- but we’ve got
better separation
between the different HTTP methods - View CODE here
# views.py
from rest_framework.views import APIView
class SnippetList(APIView):
def get(self, request, format=None):
# this request is different from normal requst(used in fxn based)
...
class SnippetDetail(APIView):
def get_object(self, pk)
...
def get(self, request, pk, format=None):
...
# snippets/urls.py
urlpatterns = [
path('snippets/', views.SnippetList.as_view()),
path('snippets/<int:pk>/', views.SnippetDetail.as_view())
]
- APIView Pagination
Mixins class based views
The mixin classes provide action methods(list, create)
rather than defining the handler methods, such as .get() and .post(), directly
We’re then explicitly binding the get and post methods
to the appropriate actions.
Doc: https://www.django-rest-framework.org/api-guide/generic-views/#mixins
# action methods - handler methods
list() - get() - list_all
retrieve() - get() - list_one
create() - post()
update() - put()
destroy() - delete()
View CODE here: https://github.com/amrit94/drf-test/blob/05-Mixin-Views/snippets/views.py
from rest_framework import mixins, generics
class SnippetList(mixins.ListModelMixin, mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) # list
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs) # create
class SnippetDetail(mixins.RetrieveModelMixin,mixins.UpdateModelMixin,
mixins.DestroyModelMixin, generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs) # retrive
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs) # update
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs # destroy
queryset
andserializer_class
—> can’t modify their names
Generic class based views
Using the mixin classes we’ve rewritten the views to use slightly less code than before, but we can go one step further.
REST framework provides a set of already mixed-in generic views
that we can use to trim down our views.py module even more.
Doc: https://www.django-rest-framework.org/api-guide/generic-views/#concrete-view-classes
from rest_framework import generics
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer