Django REST framework 学习笔记(五)

关系和超链接API

之前我们的API中的关系是使用主键表示的。在接下来,我们将通过使用超链接建立关系来提高API的内聚性和可发现性。

为API的根创建端点

  • 现在我们有snippetsusers的端点,但我们的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函数来返回完全限定的URL
URL模式由URL的名称标识,我们将在后面声明snippets/urls.py

为代码高亮创建端点

  • 我们之前一直没有写让代码高亮的端点,接下来我们为代码高亮创建端点
  • 与其他API端点不同的是,我们不想使用JSON,而只是用HTML来呈现
  • REST框架提供了两种HTML呈现器样式,一种用于处理使用模板呈现的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)
  • 为API根和代码高亮添加URL,在snippets/urls.py文件中添加
path('', views.api_root),
path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view()),

超链接API

  • 处理实体之间的关系是Web API设计中更具挑战性的方面之一,我们可以选择多种不同的方式来表示关系:
  1. 使用主键
  2. 在实体之间使用超链接
  3. 在相关实体上使用唯一标识字段
  4. 使用相关实体的默认字符串表示形式
  5. 将相关实体嵌套在父表示中
  6. 一些其他自定义表示
  • 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-detailurl模式

因为我们的URL已经包含了.json格式后缀,我们还需要在highlight字段上指明它返回的超链接的后缀格式应该使用.html

给URL模式命名

  • 我们要使用超链接API,则需要确保命名我们的URL模式
  • 我们需要命名的URL模式:
  1. 我们的API的根是指user-listsnippet-list
  2. 我们的snippets序列化程序包含一个引用的字段snippet-highlight
  3. 我们的users序列化程序包含一个引用的字段snippet-detail
  4. 我们的snippetsusers序列化程序包含url字段,默认情况下将引用{model_name}-detail,在本例中为snippet-detailuser-detail
  • 接下修改snippets/urls.py文件,文件最终应如下所示:
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

# API 端点
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')
])

添加分页

userssnippets的列表视图最终可能会返回很多实例,因此我们希望对结果进行分页,并允许API客户端逐步浏览每个页面。

通过修改settings.py文件来更改默认列表样式以使用分页。添加以下设置:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

测试API

测试方法与之前一致

发布了37 篇原创文章 · 获赞 17 · 访问量 6693
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览