What does django rest framework mean trade offs between view vs viewsets?

后端 未结 1 1531
生来不讨喜 2021-02-20 18:46

I don\'t know why document said \"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 in

  • 2021-02-20 19:25

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


    In response to your comment, here's an example in code. If I had the following models:


    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...
    def dust_everything(request):
        today = datetime.date.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.

    0 讨论(0)