How to prefer which one of generics and viewset to use? in other words when should I use generics and when should I use viewset for building api. I know that they do the same thing, but viewset has routers, so in what situation generics are better than viewset?
APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.
A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as . get() or . post() , and instead provides actions such as . list() and . create() .
Generic ViewSets are bare-bone versions of Model ViewSets. They don't come with the out of the box implemented endpoints. They do however, come with the get_queryset and the get_serializer_class methods.
They are different, let's see.
DRF has two main systems for handling views:
get
, post
, put
, patch
, and delete
.list
: read only, returns multiple resources (http verb: get
). Returns a list of dicts.retrieve
: read only, single resource (http verb: get
, but will expect an id in the url). Returns a single dict.create
: creates a new resource (http verb: post
)update/partial_update
: edits a resource (http verbs: put/patch
)destroy
: removes a resource (http verb: delete
)Both can be used with normal django urls.
Because of the conventions established with the actions, the ViewSet
has also the ability to be mapped into a router, which is really helpful.
Now, both of this Views, have shortcuts, these shortcuts give you a simple implementation ready to be used.
GenericAPIView: for APIView
, this gives you shortcuts that map closely to your database models. Adds commonly required behavior for standard list and detail views. Gives you some attributes like, the serializer_class
, also gives pagination_class
, filter_backend
, etc
GenericViewSet: There are many GenericViewSet, the most common being ModelViewSet
. They inherit from GenericAPIView
and have a full implementation of all of the actions: list
, retrieve
, destroy
, updated
, etc. Of course, you can also pick some of them, read the docs.
So, to answer your question: DRY, if you are doing something really simple, with a ModelViewSet
should be enough, even redefining and calling super
also is enough. For more complex cases, you can go for lower level classes.
Hope to have helped you!
My golden rule for this is to use generics whenever I have to override the default methods to accomplish different specifications from list and details views.
For instance, when you have different serializer classes for listing your resources and for retrieving a resource details by id I consider that using generics is a better option since probably these two endpoints' logic is going to evolve separately. Keep in mind is a good practice to maintain different logics decoupled.
When your endpoint is very simple and you don't need to customize logic between list/create and retrieve/update/delete operations you can use viewset, but yet having in mind it may be good to separate it in two views in case these operations' logic start growing in different paths.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With