前面章节中我们创建的API中的关系都是通过使用主键来表示的。在本章节中,将改进API的内聚力和可发现性,而不是使用超链接来进行关系。

为API创建一个根路径

目前现有的路径有:snippets和users,但是我们的API没有一个入口点。我们将使用一个常规的基于函数的视图和我们前面介绍的@api_view装饰器创建一个。在snipptes/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({
        "user": reverse("user-list", request=request, format=format),
        "snippets": reverse("snippet-list", request=request, format=format)
    })

需要主可以的两点是:1.我们使用REST framework的reverse函数返回完全限定的URL;2.URL模型通过snippets/urls.py中声明的遍历名称进行标识,后面将对其新增配置。

为高亮显示snippets创建路由

我们API中目前还缺少一个代码高亮的显示路径。
与其他API路径不同,这次只是需要HTML表示而不是JSON。REST框架提供了两种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中的URLconf为新创建的视图添加路劲:

urlpatterns = [
    ...
    # 根路径
    path("", views.api_root, name="index"),
    # 代码高亮
    path("snippet/<int:pk>/highlight/", views.SnippetHighlight.as_view(), name="snippet-detail-highlight"),
]

超链接我们的API

处理好实体之间的关系式Web API设计中更具挑战性的方面。可以选择几种不同的方式来代表一种关系:

  • 使用主键。
  • 在实体之间使用超链接。
  • 在相关实体上使用唯一的标识字段。
  • 使用相关实体的默认字符串表示形式。
  • 将相关实体嵌套在父表示中。
  • 一些其他自定义表示。
    REST框架支持这些所有的方式,并且可以将它们应用于正向或反向关系,也可以在诸如通用外键之类的自定义管理器上应用。
    在这种情况下,我们希望在实体之间使用超链接方式。这样的话,我们需要修改我们的序列化器的代码来扩展HyperlinkedModelSerializer而不是现有的ModelSerializer
    HyperlinkedModelSerializerModelSerializer的区别:
  • 默认情况下不包括id字段。
  • 它包含要一个url字段,使用HyperlinkedIdentityField
  • 关联关系使用HyperlinkedRelatedField,而不是PrimaryKeyRelatedField
    示例:
    ```python
    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')

### 确保URL模式被命名
如果要使用超链接的API,那么需要确保为URL模式命名。
```python
# snippets/urls.py
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views


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

添加分页

列表视图页面最终可能会返回很多实例,如果希望对结果进行分页,并允许API客户端逐步浏览也每个页面。可以在tutorial/settings.py稍微修改文件来更改默认列表样式以使用分页。添加设置如下:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}
0条评论

相关推荐

django教程

r

Django 2019-05-20 10:53:53

Celery

celery学习资料

Django 2019-05-25 18:41:55

django教程入门

适合django新人使用的学习手册

Django 2019-07-01 14:28:04

django实用资料

django项目从0到1自己总结的实用的资料,大部分常用的功能这里都有

Django 2019-05-08 18:21:34