django Rest Framework 系列 5 - Relationships & Hyperlinked APIs

官网地址: http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/

目前我们的API中的关系用主键表示,在本教程的这一部分中,我们将改进API的内聚力和可发现性,而不是使用关联的超链接。

1 .为API根创建一个URL
现在我们有了 snippetsusers 的url, 但没有API的入口 为了创建一个, 我们将使用基于函数的常规视图和我们前面介绍的@api_view装饰器。在 snippets/views.py 中添加:

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)
    })

这里需要注意两点:
首先, 我们使用REST框架reverse 函数是为了返回一个完全限定的URLS;
其次, URL 匹配方式通过方便的名称来标识,这个稍后会在snippets/urls.py 中声明。

2. 为语法高亮功能常见URL
很明显的意见事是我们的 API 中仍然缺少代码突出显示。
不同于其它的API,我们不想使用JSON,而只是想使用HTML表示. REST框架提供了2种 HTML渲染类型,一个用于使用模板渲染的HTML,另一个是使用已经体检构建好的HTML代码。 这里我们使用第二种方式.
在创建代码高亮视图时,我们需要考虑的另一件事是,我们可以使用现有的具体通用视图。 我们不是返回一个对象实例,而是一个对象实例的属性。
我们将使用最基础的类视图创建.get()方法来表示实例,而不是使用通用类视图。 在你的 snippets/views.py 添加:

from rest_framework import renderers
from rest_framework.response import Response

class SnippetHighlight(generics.GenericAPIView):
    queryset = Snippet.objects.all()
    renderer_classes = (renderers.StaticHTMLRenderer,)

    def get(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

snippets/urls.py 中添加以下url匹配规则:

url(r'^$', views.api_root),

然后添加一个 代码段高亮的url匹配规则

url(r'^snippets/(?P[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),


3. API超链接
处理实体之间的关系是WEB API 设计更具挑战性之一。我们可以选择很多不同方法来表示关系:
. 使用主键
. 在两个实体之间使用超链接
. 在两个相关的实体上使用唯一的标识字段
. 在两个相关的实体上使用默认的字符串表现形式
. 将相关实体嵌套在父表达式内
. 一些其它自定义表达式

REST框架支持所有这些类型,而且可以将他们应用于正向或反向关系,或者将它们应用于自定义管理器(如通用外键)。
在本例中,我们在两个实体上使用超链接的方式. 为了实现这个,我们将要修改序列化程序来扩展 HyperlinkedModelSerializer, 而不是现有的ModelSerializer
HyperlinkedModelSerializer 相比 ModelSerializer 有以下区别:
1) 默认不包含 id 字段
2) 包含一个 url 字段, 使用HyperlinkedIdentityField
3) 关系使用HyperlinkedRelatedField, 而不是PrimaryKeyRelatedField

我们可以使用超链接很容易的重写我们已存在的序列化方法, 在 snippets/serializers.py 添加:

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')

注意, 我们还添加了一个新的 highlight 字段,改字段与url 字段的类型一样, 不同之处在于它指向snippet-highlight url 匹配模式, 而不是 snippet-detail url匹配模式。
因为我们在URL中包含了类似于.json 格式的后缀. 我们还需要在highlight 字段指出,任何返回超链接的后缀格式应该使用.html 的后缀。


4. 确保URL匹配都有命名
如果我们要使用超链接的API, 我们需要确认对URL匹配进行命名(name),看看那个URL匹配需要命名:
. API的根指向user-listsnippet-list
. snippet序列化包含一个字段指向 snippet-highlight
. user 序列化包含一个字段指向 snippet-detail
. snippet 和 user 序列化包含url 字段,默认将指向{model_name}-detail, 在本例中将指向snippet-detailuser-detail

在URL配置中完成所有的命名后,我们最终的 snippet/urls.py 应该如下:

from django.conf.urls import url, include
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

# API endpoints
urlpatterns = format_suffix_patterns([
    url(r'^$', views.api_root),
    url(r'^snippets/$',
        views.SnippetList.as_view(),
        name='snippet-list'),
    url(r'^snippets/(?P[0-9]+)/$',
        views.SnippetDetail.as_view(),
        name='snippet-detail'),
    url(r'^snippets/(?P[0-9]+)/highlight/$',
        views.SnippetHighlight.as_view(),
        name='snippet-highlight'),
    url(r'^users/$',
        views.UserList.as_view(),
        name='user-list'),
    url(r'^users/(?P[0-9]+)/$',
        views.UserDetail.as_view(),
        name='user-detail')
])

# Login and logout views for the browsable API
urlpatterns += [
    url(r'^api-auth/', include('rest_framework.urls',
                               namespace='rest_framework')),
]

5. 添加分页
用户和代码段的列表视图可能会返回相当多的实例,因此我们希望对结果进行分页,并允许API客户端逐步浏览每个单独的页面。
我们可以使用分页来改变默认的列表样式, 修改我们的 tutorial/settings.py 文件, 添加如下信息

REST_FRAMEWORK = {
    'PAGE_SIZE': 10
}

注意,REST框架的配置都命名到单个字典配置中, 名为REST_FRAMEWORK, 能很好的与你的其它项目的配置分离开来。
如果需要的话我们也可以自定义分页样式,但在本例中我们使用默认的配置。

6. 浏览API
如果我们打开浏览器并跳转到可浏览的API,你会发现你可以按照你的工作方式通过链接来很简单的浏览API
你也可以看到 高亮 的snippet实例链接, 这将使您转到突出显示的HTML代码表现方式

你可能感兴趣的:(restful)