Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trade offs between view and viewsets

I don't know why the documentation says:

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.

If I want to make a REST API (like in ruby-on-rail) I think viewsets is a good approach to take.

Can anyone explain more about it?

like image 880
Burger King Avatar asked Sep 07 '15 03:09

Burger King


People also ask

What is difference between views and Viewsets?

While regular views act as handlers for HTTP methods, viewsets give you actions, like create or list . The great thing about viewsets is how they make your code consistent and save you from repetition. Every time you write views that should do more than one thing, a viewset is the thing that you want to go for.

What is difference between Api_view and 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.

When should I use ViewSet vs APIView?

APIView and ViewSet all have their right use cases. But most of the time, if you are only doing CRUD on resources, you can directly use ViewSets to respect the DRY principle. But if you are looking for more complex features, you can go low-level because after all, viewsets are also a subclass of APIView .

What are Viewsets?

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() .


1 Answers

The main advantage of using viewsets over views is brevity. In the simple case, you can get more done with fewer lines of code.

The main disadvantage is that the simplifying assumptions made by viewsets might not always fit the problem space you are working in. As with class-based views in Django, if you try to apply the wrong pattern to a problem you can end up doing more work than you need to solve a problem.

My personal heuristic is that if I am doing the full set of CRUD operations on a model, I start with viewsets and go from there until I feel the convenience they provide is no longer worth the trouble I am incurring in that specific instance; if I am working with an API endpoint that doesn't map to any models, I'm far more likely to just use a view.

If I had the following models:

models.py

from django.db import models

class Gizmo(models.Model):
    name = models.CharField(blank=True, null=False)
    last_dusted = models.DateField(null=True)

class Sprocket(models.Model):
    nom = models.CharField(blank=True, null=False)
    last_dusted = models.DateField(null=True)

And I wanted to support the standard HTTP methods with their normal meanings, (namely GET and POST on the list view and GET, PUT, and DELETE on the detail view), I'd create a GizmoViewSet, a SprocketViewSet and call it a day.

Say I also wanted to offer API consumers the ability to dust off all of the gizmos at once. In that case, it would make sense to add a dust method to the GizmoViewSet using the @list_route decorator. Suppose that what I really wanted to do though was to offer a single endpoint where that API consumer could dust all the Gizmos and the Sprockets off at once. That doesn't really map very well to either viewset, so I'd add a one off view:

import datetime

from rest_framework.decorators import api_view
from rest_framework.response import Response

from my_app.models import Gizmo, Sprocket

# I used a function-based API view here, but a CBV APIView
# would work just as well. Matter of personal preference...
@api_view
def dust_everything(request):
    today = datetime.date.today()
    Gizmo.objects.all().update(last_dusted=today)
    Sprocket.objects.all().update(last_dusted=today)
    return Response({"status_of_dusting": "successful"})

So in that case I wouldn't be tearing out all my viewsets and replacing them with views; I'm adding an extra view to supplement the existing viewsets where it makes sense.

like image 158
chucksmash Avatar answered Sep 20 '22 21:09

chucksmash