Django REST framework -- Relationships & Hyperlinked APIs

Relationships & Hyperlinked APIs

https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/

对于表之间的关联关系, ModelSerializer 默认是使用 外键 的ID 作为序列化返回值的。

但是 对于web应用来说, 其更想知道 API形式的URL.

At the moment relationships within our API are represented by using primary keys. In this part of the tutorial we'll improve the cohesion and discoverability of our API, by instead using hyperlinking for relationships.

使用此类后, 会新增一个 url field, 此结果序列化后, 就是url

class SnippetSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')

    class Meta:
        model = Snippet
        fields = ['url', 'id', 'highlight', 'owner',
                  'title', 'code', 'linenos', 'language', 'style']


class UserSerializer(serializers.HyperlinkedModelSerializer):
    snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)

    class Meta:
        model = User
        fields = ['url', 'id', 'username', 'snippets']

每一个path都定义了name, 便于进行反向查询。

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

# API endpoints
urlpatterns = format_suffix_patterns([
    path('', views.api_root),
    path('snippets/',
        views.SnippetList.as_view(),
        name='snippet-list'),
    path('snippets/<int:pk>/',
        views.SnippetDetail.as_view(),
        name='snippet-detail'),
    path('snippets/<int:pk>/highlight/',
        views.SnippetHighlight.as_view(),
        name='snippet-highlight'),
    path('users/',
        views.UserList.as_view(),
        name='user-list'),
    path('users/<int:pk>/',
        views.UserDetail.as_view(),
        name='user-detail')
])

通过reverse 接口, 查询出完整的url返回给客户端。

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse


@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'snippets': reverse('snippet-list', request=request, format=format)
    })

reverse

https://docs.djangoproject.com/en/3.2/ref/urlresolvers/#django.urls.reverse


django.urls utility functions

reverse()

If you need to use something similar to the url template tag in your code, Django provides the following function:

reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

viewname can be a URL pattern name or the callable view object. For example, given the following url:

from news import views

path('archive/', views.archive, name='news-archive')

you can use any of the following to reverse the URL:

# using the named URL
reverse('news-archive')

# passing a callable object
# (This is discouraged because you can't reverse namespaced views this way.)
from news import views
reverse(views.archive)
出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
原文地址:https://www.cnblogs.com/lightsong/p/15400170.html