【发布时间】:2015-12-02 12:55:22
【问题描述】:
我不知道为什么documentation 说:
这并不意味着它总是正确的方法。在使用基于类的视图而不是基于函数的视图时,需要考虑一组类似的权衡。使用视图集不如单独构建视图那么明确。
如果我想制作一个 REST API(比如在 ruby-on-rail 中),我认为 viewsets 是一个不错的方法。
谁能解释一下?
【问题讨论】:
我不知道为什么documentation 说:
这并不意味着它总是正确的方法。在使用基于类的视图而不是基于函数的视图时,需要考虑一组类似的权衡。使用视图集不如单独构建视图那么明确。
如果我想制作一个 REST API(比如在 ruby-on-rail 中),我认为 viewsets 是一个不错的方法。
谁能解释一下?
【问题讨论】:
使用viewsets 而不是views 的主要优点是简洁。在简单的情况下,您可以用更少的代码行完成更多工作。
主要缺点是viewsets 所做的简化假设可能并不总是适合您正在处理的问题空间。与 Django 中基于类的视图一样,如果您尝试将错误的模式应用于问题,您可以最终做的工作超出了解决问题所需的工作量。
我个人的启发是,如果我在一个模型上执行全套 CRUD 操作,我会从 viewsets 开始,然后从那里开始,直到我觉得他们提供的便利不再值得我在其中遇到的麻烦具体实例;如果我正在使用不映射到任何模型的 API 端点,我更有可能只使用 view。
如果我有以下型号:
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)
我想支持标准 HTTP 方法的正常含义(即列表视图上的 GET 和 POST 以及详细视图上的 GET、PUT 和 DELETE),我将创建一个GizmoViewSet,一个@ 987654329@ 收工。
假设我还想为 API 使用者提供一次清除所有小玩意儿的能力。在这种情况下,使用 @list_route 装饰器将 dust 方法添加到 GizmoViewSet 是有意义的。假设我真正想做的是提供一个单一的端点,API 使用者可以一次清除所有的Gizmos 和Sprockets。这并不能很好地映射到任何一个视图集,所以我会添加一个一次性视图:
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"})
所以在这种情况下,我不会撕掉我所有的视图集并用视图替换它们;我正在添加一个额外的视图来补充现有的有意义的视图集。
【讨论】: