Django REST Framework: when to create a hyperlinked resource and when nested resource? How to POST a nested resource?

こ雲淡風輕ζ 提交于 2019-12-05 16:56:38

问题


I'm building a REST web API using the Django REST Framework. Things are going great, but I have, however stumbled upon a problem with nested resources. At first, all relationships in the REST API were hyperlinked. A post, for example, looked like this:

{
    "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
}

The relationship between the post and the author (user) is hyperlinked. When you want to create a new post, you need to specify a correct hyperlink to a specific user - this works fine.

When calling a list of posts, things become inefficient, because you have to make an extra API call for every author for every post. I solved this by using NESTED resources instead of HYPERLINKED resources, so every post now contains all the information about the author.

{
    "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
}

My first question is: do you have a guideline, whether I should create a nested data structure or a separate endpoint with hyperlink to it.

My second question is: when I use author as a nested resource and want to create a new post, I don't want to specify all the information about the author (username, e-mail, ...). Is there any way to just use a link to a user for the CREATE/UPDATE operation? Or modify something so that the user ID is enough to fill in this field?


回答1:


If i understood your question correctly, You want to have expanded author while you are retrieving the data and just want to send ID or URL in case of update and create.

1# It is not about any guideline and it totally depends on your requirement of how your api is going to be used.

2# So you need to extend your UserSerializer and override to_internal_value. Sample code might look like

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)

Notice that you must have a Endpoint for user-detail in able to work with HyperLinkedRelatedField.

So If you want to be able to send ID then sample code might look like

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)

However i would like to keep consistency in sending ForeignKey field in POST/PUT/PATCH. (Always Either URL or ID).

then use it in your code like

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

    class Meta:
        model = Post

Please see the documentation on Writable nested serializers to POST on a Nested resource.



来源:https://stackoverflow.com/questions/26899976/django-rest-framework-when-to-create-a-hyperlinked-resource-and-when-nested-res

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!