我正在使用Django REST Framework构建REST Web API。事情进展顺利,但我遇到了嵌套资源的问题。首先,REST API中的所有关系都是超链接的。例如,帖子看起来像这样:
{
"path": "http://api.myproject.com/posts/1.json",
"id": 1,
"author": "http://api.myproject.com/users/broak.json",
"image": "/images/posts/cxyUzlPo.jpg",
"header": "Who am I?",
"footer": "I am a champion!",
"date": "2014-11-09 15:16",
"likes": "http://api.myproject.com/posts/1/likes.json",
"comments": "http://api.myproject.com/posts/1/comments.json",
"likes_count": 0,
"comments_count": 0
}
帖子和作者(用户)之间的关系是超链接的。如果要创建新帖子,则需要指定指向特定用户的正确超链接 - 这样可以正常工作。
在调用帖子列表时,事情变得低效,因为您必须为每个帖子为每个作者进行额外的API调用。我通过使用NESTED资源而不是HYPERLINKED资源解决了这个问题,所以现在每个帖子都包含有关作者的所有信息。
{
"path": "http://api.myproject.com/posts/1.json",
"id": 1,
"author": {
"email": "broak@gmail.com"
"username": "broak",
"first_name: "John",
"last_name": "Broak",
"is_staff": False,
"is_active": True,
"last_login": "02-26-2016"
},
"image": "/images/posts/cxyUzlPo.jpg",
"header": "Who am I?",
"footer": "I am a champion!",
"date": "2014-11-09 15:16",
"likes": "http://api.myproject.com/posts/1/likes.json",
"comments": "http://api.myproject.com/posts/1/comments.json",
"likes_count": 0,
"comments_count": 0
}
我的第一个问题是:你是否有一个指南,我是否应该创建一个嵌套的数据结构或一个带有超链接的单独端点。
我的第二个问题是:当我将作者用作嵌套资源并希望创建新帖子时,我不想指定有关作者的所有信息(用户名,电子邮件,...)。有没有办法只使用一个用户链接进行CREATE / UPDATE操作?或修改一些内容,以便用户ID足以填写此字段?
答案 0 :(得分:7)
如果我正确理解了您的问题,您希望在检索数据时扩展作者,并且只是想在更新和创建时发送ID或URL。
1#
这与任何指南无关,完全取决于您对api
将如何使用的要求。
2#
因此,您需要延长UserSerializer
并覆盖to_internal_value
。示例代码可能类似于
class MyCustomSerializer(UserSerializer):
def to_internal_value(self, data):
# data must be valid user-detail url
return serializers.HyperLinkedRelatedField(queryset=User.objects.all(), view_name='user-detail').to_internal_value(data)
请注意您必须拥有能够使用HyperLinkedRelatedField的用户详细信息的端点。
因此,如果您希望能够发送ID
,那么示例代码可能看起来像
class MyCustomSerializer(UserSerializer):
# data must be valid user id
def to_internal_value(self, data):
return serializers.PrimaryKeyRelatedField(queryset=User.objects.all()).to_internal_value(data)
但是我希望在POST/PUT/PATCH
中发送ForeignKey字段保持一致。 (始终是URL或ID)。
然后在您的代码中使用它,如
class PostSerializer(serializers.HyperlinkedModelSerializer):
author = MyCustomSerializer()
class Meta:
model = Post
请参阅嵌套资源上Writable nested serializers至POST
的文档。