Django REST框架:什么时候创建超链接资源和何时嵌套资源?如何发布嵌套资源?

Bra*_*aek 10 django rest resources hyperlink django-rest-framework

我正在使用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
}
Run Code Online (Sandbox Code Playgroud)

帖子和作者(用户)之间的关系是超链接的.如果要创建新帖子,则需要指定指向特定用户的正确超链接 - 这样可以正常工作.

当调用帖子列表时,事情变得低效,因为你必须为每个帖子为每个作者进行额外的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
}
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是:你是否有一个指南,我是应该创建一个嵌套数据结构还是一个带有超链接的单独端点.

我的第二个问题是:当我使用作为嵌套资源并想要创建新帖子时,我不想指定有关作者的所有信息(用户名,电子邮件,...).有没有办法只使用一个用户链接进行CREATE/UPDATE操作?或修改一些内容,以便用户ID足以填写此字段?

Sat*_*eet 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)
Run Code Online (Sandbox Code Playgroud)

请注意,您必须拥有能够使用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)
Run Code Online (Sandbox Code Playgroud)

但是我想在发送ForeignKey字段时保持一致性POST/PUT/PATCH.(始终是URL或ID).

然后在你的代码中使用它

class PostSerializer(serializers.HyperlinkedModelSerializer):
    author = MyCustomSerializer()

    class Meta:
        model = Post
Run Code Online (Sandbox Code Playgroud)

请参阅有关文件可写嵌套的序列化POST一个嵌套的资源.