Skip to main content
 首页 » 编程设计

python之如何考虑 Django 的普通基于类的 View 与使用 REST API

2024年08月23日28haluo1

我一直在用 Django 编写一个网络应用程序,以取代我和一些 friend 玩的笨拙的、基于电子表格的体育挑选游戏。我学到了很多东西,并且很高兴了解 Django 以及如何从头开始构建这样的东西。

我最近意识到我想在前端使用更强大的东西(Ember、Angular 等),最终目标是单页应用程序。为此,我安装了 Django REST Framework (DRF) 并开始阅读文档并按照教程进行操作。这非常有趣,我终于开始明白为什么带有 API 的客户端-服务器模型确实是实现流畅交互的唯一方法,而这种交互现在已经结束了。

我正在尝试将我的一个基于类的 View 实现为 API 端点,但我在概念化它时遇到了很多麻烦。我想我应该从一个简单的、仅限 GET 的端点开始——这是我试图以 API 形式复制的简单 CBV:

class MatchupDetail(DetailView): 
  template_name = 'app/matchups.html' 
  context_object_name = 'pick_sheet' 
 
  def get_object(self): 
    #logic to find and return object 
 
  def get_opponent(self,username,schedule,week, **kwargs): 
    #logic to find and return the opponent in the matchup 
 
  def get_context_data(self, **kwargs): 
    context = super().get_context_data(**kwargs) 
    #logic to pull the opponents details and set them in the context 

我觉得我可以处理这个流程 - 用户点击一个链接,这个 View 检索位于请求页面中心的对象,用上下文中的内容补充它,然后呈现它。

当我开始考虑将它变成一个 API 端点时,它并没有多大意义。我应该将所有与用户相关的数据放入一个 JSON 响应中吗?或者前端是否应该基本上处理此逻辑流,而 API 仅由一组端点组成 - 例如,一个端点用于检索对象,一个或多个端点用于检索上下文中正在传递的内容?

促使我写这篇文章的原因是我对上述 View 的( super 基础)API 实现遇到了一些问题:

class MatchupDetailApi(generics.ListAPIView): 
 
  queryset = Sheet.objects.all() 
  serializer_class = SheetSerializer 

使用序列化器:

class SheetSerializer(serializers.ModelSerializer): 
  user = serializers.ReadOnlyField() 
 
  class Meta: 
    model = Sheet 

当我注意到没有它时,我添加了用户字段,返回的序列化 Sheet 对象实际上只是数据库中的行 - 一个整数 ID,用户对象的整数外键,等等。使用“传统的”CBV,整个对象都返回到模板 - 因此访问相关字段非常直观,使用 Django 也可以轻松遍历对象关系。

REST 实现是否提供相同类型的东西?从我读过的内容来看,似乎我需要扩展 DRF (django-rest-multiple-models) 才能在单个响应中返回多个模型,这让我认为我应该为每个模型创建端点模型,并将表示逻辑留给我处理前端。那是典型的吗? 或者有一个 API 端点确实返回一个对象和几个相关对象之类的东西是否可行?

注意:当我将用户添加到 SheetSerializer 时,上面的基本端点停止工作。我意识到我也应该有一个 UserSerializer,它是:

class UserSerializer(serializers.HyperlinkedModelSerializer): 
  class Meta: 
    model = User 

但是,当我尝试浏览 API 时,我收到第一个用户不可序列化的 TypeError。具体来说:<User: dkhaupt> is not JSON serializable .这不是 UserSerializer 的用途吗?

请您参考如下方法:

Is it feasible to have an API endpoint that does return something like an object and several related objects?

是的!

听起来您的开端不错。我会像这样构造它:

class UserSerializer(serializers.ModelSerializer): 
    """serializes a user""" 
    class Meta: 
        model = User 
        fields = ('id', 'first_name', 'last_name',) 
 
 
class SheetSerializer(serializers.ModelSerializer): 
    """serializes a sheet, and nests user relationship""" 
    user = UserSerializer(read_only=True) 
 
    class Meta: 
        model = Sheet 
        fields = ('id', 'sheet_name', 'user',) 

我认为您不需要 django-rest-multiple-models 来实现您想要实现的目标。在我的草图中(我猜测字段名),您将序列化工作表以及关联的用户对象。