Django REST framework 学习纪要 Tutorial 5 Relationships & Hyperlinked APIs

目前我们使用主键来表示模型之间的关系。在本章,我们将提高API的凝聚性和可读性。

为我们API的根节点创建URL

之前我们给snippetsusers创建了URL接口,但我们没有一个根节点的URL。
在此我们创建一个简单的,基于函数的views,并为它加上@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方法来返回完全符合规则的url
  • url参数将会与我们之后在snippets/urls中定义的相同

编写snippets/urls.py

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

为高亮代码创建URL

接下来我们需要为高亮代码提供接口,和其它的接口不同,这个接口我们需要展现渲染好的HTML页面,而不是JSON。
REST框架给我们提供了两种HTML展现形式,一种是使用模板渲染,一种是使用已经提前渲染好的HTML,在此我们使用第二种。
另外,我们需要考虑当创建代码高亮的view时,我们没有现成的类来继承,因为我们不是返回对象,而是返回对象的一个属性,我们需要重写父类的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(r'^snippets/(?P[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),

API之间使用超链接

在Web API中处理各个API之间的关系是一件非常头疼的事情,通常有以下方法表示关系:

  • 使用主键
  • 在API之间使用超链接
  • 在关联API之间使用唯一字段表示
  • 在关联API之间使用默认字符串表示
  • 将一个API嵌套在另一个API类中
  • 其它

REST框架支持上述所有方法,并且可以应用于正向、反向关系或类似外键这类自定义管理项。
在这里我们使用超链接来处理之间的关系,因此我们需要修改serializers,使用HyperlinkedModelSerializer替代原先的ModelSerializer:

  • 默认不包含主键
  • 使用HyperlinkedRelatedField时,需要在Meta子类的fields中包含``urls`字段
  • 使用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')

这里在SnippetSerializer中新增了一个highlight属性,这个属性和url字段类型相同,区别在于它指向的是snippet-highlight而非snippet-detail
另外,由于我们有.json格式的后缀,我们需要指定highlight字段使用.html来返回相应的格式

确保URL都被命名

在此之前我们创建了一些url参数,在此罗列:

  • 根节点指向了user-listsnippet-list
  • snippet serializer包含了一个指向snippet-highlight的url的字段
  • user serializer包含了指向snippet-detail的url的字段
  • snippet serializeruser serializer都包含了url字段,这个字段默认指向{model_name}-detail,这里分别是snippet-detailuser-detail

编辑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')),
]

添加分页

后面可能会有很多个数据产生,我们需要对返回结果进行分页,修改tutorial/settings.py

REST_FRAMEWORK = {
    'PAGE_SIZE': 10
}

注意,所有关于REST框架的settings都在一个叫做REST_FRAMEWORK的字典中,这帮助我们与其他的settings分离开来。

关于

本人是初学Django REST framework,Django REST framework 学习纪要系列文章是我从官网文档学习后的初步消化成果,如有错误,欢迎指正。

学习用代码Github仓库:shelmingsong/django_rest_framework

本文参考的官网文档:Tutorial 5: Relationships & Hyperlinked APIs

博客更新地址

  • 宋明耀的博客 [ 第一时间更新 ]
  • 知乎专栏 Python Cookbook
  • 流月0的文章

你可能感兴趣的:(Django REST framework 学习纪要 Tutorial 5 Relationships & Hyperlinked APIs)