Generic ViewSets — An Introduction

Caronex Labs
Django Rest for Not Beginners
4 min readJul 5, 2020

Glad to have you onboard! This is the starting line. An introduction to Generic ViewSets, their uses and how to customize them to fit your needs.

I believe the best place to start is to see where we need to end up. And we have a very simple aim... we need to build this:

The Medium Profile Page… with a few additions.

For those of you who just went to their profile pages to see the article count, welcome back. For those who didn’t, please have a good look at the above image… we’re going to be staring at it quite a bit throughout this series.

Like I promised in the Prologue, here are a list of things you should be familiar with:

Setting The Project Up

…The author then set the project up…

Here is the directory structure to make you feel a little comfortable…

We will be working primarily with the users_module directory. You can find this project here.

Let’s start with the models. We will only consider the User model for now. Let’s deal with the articles themselves a little later.

An aside on the AbstractUser:Traditionally, if we wanted the User of our system to have more fields (in our case we have the bio, the headline etc). We would make a model, usually called `profile` and then have a one-to-one relation with the user model. However, the recommended way now is to use AbstractUser. AbstractUser is a way for you to extend your User model without completely overwriting the inbuilt Django User model. As you can see below, we inherit the AbstractUser and we don't need the `models.Model`. I have mentioned it in the comments below as well, that the first 5 fields do not need to be mentioned, they will be there even if we don't write them explicitly.For more information, I highly recommend this article by Vitor Freitas - Simple Is Better Than Complex: How To Extend The Django User Model

Here is the User model:

users_module/models.py

Now, there are a few things that should strike you as problematic:

  • We would never store articles or following this way. They are both dynamic properties and should be calculated in the serializer, the view or by using a computed property (We will talk about this in a future series).
  • The headline is dynamic as well and should be calculated in a view.
  • The bio should have a max length.

We will fix these issues eventually, but they are actually going to force us to use the topics we discuss in this series.

Let’s talk about the views now. We will assume that we only want to retrieve information for now. Here is the way we would do it using ModelViewSet :

users_module/views.py

The serializer is simple:

users_module/serializers.py

This is ugly. There is redundancy in the code, we are repeating ourselves multiple times, and I’m confident my editor thinks I’m stupid.

Many of you will very rightly point out that ModelViewSets were not meant for a single endpoint. They are meant to make it easier to build multiple endpoints that pertain to the same model. But scalability is something a developer should always keep in mind, your code should be future proof. In our case, we will be adding more endpoints in the future.

Here is the Generic ViewSet doing the same thing:

The only change you will notice is the ListModelMixin. We have inherited a class ListModelMixin in our original UserViewSet.

A mixin is basic python class inheritance. When I include the ListModelMixin, there is a piece of code that is included in the current class without me having to explicitly write it.

Here is the code if you wanna have a look:

This is the same list endpoint that is auto created when you use ModelViewSet.

So basically, you can now choose which endpoints you want and which ones are not relevant. Similar to this, there are:

  • CreateModelMixin
  • UpdateModelMixin
  • RetrieveModelMixin
  • DestroyModelMixin

Pro Tip: Your view won't work if the mixins are not the first to be inherited.

class UserViewSet(GenericViewSet, ListModelMixin) --- Wrong

class UserViewSet(ListModelMixin, GenericViewSet) --- Correct

We have not yet dealt with the get_queryset() issue. The fact that we’re using a get_queryset method that only returns a single User object. But that’s also a set-up for a future article.

Essentially,

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.

Well, that’s it for this one. We set the project up and explored the basic difference between GenericViewSets and ModelViewSets. In the upcoming articles however, things get a little more interesting when we talk about custom endpoints.

I hope to see you soon…

--

--