【问题标题】:Django REST Framework: when to create a hyperlinked resource and when nested resource? How to POST a nested resource?Django REST Framework:何时创建超链接资源以及何时嵌套资源?如何发布嵌套资源?
【发布时间】:2015-01-10 01:44:45
【问题描述】:

我正在使用 Django REST 框架构建一个 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足以填写这个字段?

【问题讨论】:

    标签: django rest hyperlink resources django-rest-framework


    【解决方案1】:

    如果我正确理解了您的问题,您希望在检索数据时扩展作者,并且只想发送 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)
    

    注意,您必须有一个 Endpoint 用于用户详细信息才能使用 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 serializersPOST 的文档。

    【讨论】:

      猜你喜欢
      • 2014-12-15
      • 2017-10-19
      • 2015-09-18
      • 2014-05-14
      • 2013-06-25
      • 2013-10-16
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      相关资源
      最近更新 更多