在 DRF 中使用 HyperlinkedModelSerializer 有啥好处?

Posted

技术标签:

【中文标题】在 DRF 中使用 HyperlinkedModelSerializer 有啥好处?【英文标题】:What is the benefit of using a HyperlinkedModelSerializer in DRF?在 DRF 中使用 HyperlinkedModelSerializer 有什么好处? 【发布时间】:2016-01-30 00:04:18 【问题描述】:

关于this link,我已经看到很多在 Django Rest Framework 中使用 HyperlinkedModelSerializer 的示例。它说:

HyperlinkedModelSerializer 类类似于 ModelSerializer 类,除了它使用超链接来表示关系, 而不是主键。

我的问题是,与常规模型序列化器相比,使用它们的用例/好处是什么?

【问题讨论】:

【参考方案1】:

唯一的区别是,正如您在引用中所引用的那样,主键和外键由指向这些资源的 URL 表示,而不仅仅是实际的键值。

好处是当您想要检索相关对象时,您不必在前端构造资源 URL。

另一件事完全是嵌套表示,它允许您在序列化器输出中内联相关对象。当您认为 API 使用者立即拥有相关项目而不是发出额外请求来检索它们更方便时,可以将其与 ModelSerializerHyperlinkedModelSerializer 结合使用。

可以通过Meta.depth 选项或使用相关模型的序列化程序而不是RelatedField 来实现嵌套表示。

正如@xleon 在他的评论中所说,使用 URL 作为键可以让其他开发人员更容易理解您的 API。

【讨论】:

不错的答案,我只想添加一件事:在您的资源中使用超链接将使任何开发人员更容易使用您的 Web API。如果他们可以看到整个资源 URI,他们将不需要任何文档或其他方法来找到它【参考方案2】:

我们需要在 Web API 设计中实现实体之间的关系。 有几种方法可以做到这一点(如 DRF 文档中所述):

使用主键。 在实体之间使用超链接。 在相关实体上使用唯一标识 slug 字段。 使用相关实体的默认字符串表示。 将相关实体嵌套在父表示中。 其他一些自定义表示

HyperlinkedModelSerializer 与 ModelSerializer 有以下区别:

默认不包含id字段。 它包含一个 url 字段,使用 HyperlinkedIdentityField。 关系使用 HyperlinkedRelatedField,而不是 PrimaryKeyRelatedField。

一个简单的例子:

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name')

bash> http -a admin:yourpassword http://127.0.0.1:8000/users/

 "results": [
        
            "email": "admin@min.com",
            "groups": [
                "http://127.0.0.1:8000/groups/1/",
                "http://127.0.0.1:8000/groups/2/"
            ],
            "url": "http://127.0.0.1:8000/users/1/",
            "username": "admin"
        
    ]

但是如果你改变了

class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ('url', 'username', 'email', 'groups')

结果将是:

   "results": [
        
            "email": "admin@min.com",
            "groups": [
                1,
                2
            ],
            "url": "http://127.0.0.1:8000/users/1/",
            "username": "admin"
        
    ]

【讨论】:

【参考方案3】:

应该注意 HyperlinkedModelSerializers 的一个成本是,如果您的 API 支持通过 URL 中的查询参数进行过滤或排序,那么您的前端消费者使用超链接 url 字段来构建查询参数会有点困难,因为他们必须从 URL 中解析出 pk,而不是让 pk 直接可用。

例如,假设路由上的对象/api/objects/12/ 消费者需要解析url 字段以提取12,以便在另一个端点上通过此对象构造查询过滤:/api/otherobjects/?object=12 .不是一个大问题,但如果您打算进行大量过滤,那就太可惜了。

【讨论】:

解决这个问题的简单方法是在序列化程序中添加“id”字段:id = serializers.ReadOnlyField()

以上是关于在 DRF 中使用 HyperlinkedModelSerializer 有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章

drf Serializer使用

“未提供身份验证凭据。”在 DRF 中

drf基本使用

如何在 DRF 测试中使用 JWT 令牌?

在 Django/DRF 中使用 JWT 身份验证并将 JWT 存储在 HttpOnly Cookie 中

在 Django (DRF) 中使用外部 API 进行基于令牌的身份验证