在参考this link时,我已经看到很多在Django Rest Framework中使用HyperlinkedModelSerializer的例子。它说:
HyperlinkedModelSerializer类与ModelSerializer类似 除了它使用超链接来表示关系, 而不是主键。
我的问题是,使用它们与常规模型序列化器相比有什么用例/好处?
答案 0 :(得分:27)
唯一的区别是,如您所引用的那样,主键和外键由指向这些资源的URL表示,而不仅仅是实际的键值。
好处是,当您想要检索相关对象时,您不必在前端构建资源URL。
另一件事完全是嵌套表示,它允许您在串行器输出中内联相关对象。当您认为API使用者更方便地拥有相关项目而不是提供其他请求来检索它们时,这可以与ModelSerializer
和HyperlinkedModelSerializer
结合使用。
嵌套表示可以通过Meta.depth
选项或使用相关模型的序列化程序而不是RelatedField
来实现。
正如@xleon在评论中所说的那样,使用URL作为密钥使其他开发人员更容易理解您的API。
答案 1 :(得分:24)
我们需要在Web API设计中实现实体之间的关系。 有几种方法可以做到这一点(如DRF文档所述):
HyperlinkedModelSerializer与ModelSerializer有以下不同之处:
一个简单的例子:
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"
}
]
答案 2 :(得分:1)
应该注意的HyperlinkedModelSerializers的一个代价是,如果您的API支持通过URL中的查询参数进行过滤或排序,那么您的前端使用者使用超链接的url字段来构造查询参数更加困难,因为他们必须从URL解析出pk而不是直接使用pk。
例如,假设/api/objects/12/
路径上的对象,消费者需要解析url
字段以提取12
,以构建此对象的查询过滤另一个端点:/api/otherobjects/?object=12
。这不是一个大问题,但如果你计划进行大量过滤,那就太糟糕了。