Django-Rest-Framework 教程: 5. 提高关联性和超链接API

it2022-05-09  55

到目前为止, API之间的关系是以主键形式体现的, (比如打开/users/1/, 可以看到snippets中为snippet的主键). 在本篇中, 我们将使用超链接的形式, 进一步提高API的关联程度和可发现性. 首先我们补充一些路径, 是整个API结构更为完整.

1. 根路径

现在, 我们已经有了users和snippets的路径, 但对于API本身却没有一个根路径. 我们使用@api_view修饰器来创建一个function based view作为根路径:

# snippets/views.py from rest_framework import renderers 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) })

注意, 我们使用了django-rest-framework的reverse(), 而不是django自带的reverse(), 此时如果打开http://127.0.0.1/8000, 会报错, 因为我们还没有为url添加name, 稍后我们会添加.

在urls.py中添加对应的路径:

# snippets/urls.py url(r'^$', views.api_root),

2. 高亮snippet路径

我们还需要提供高亮snippet的路径. 当然这一路径与其他不同, 我们希望使用HTML而不是JSON来呈现. Django-rest_framework为我们提供了两种方式呈现HTML, 一种是使用模板, 另一种则是已构建好的HTML文本. 由于在创建snippet时, 我们已经使用pygments将高亮的snippet转化为HTML文本储存在数据库中, 我们使用第二种方式.

由于我们返回的并不是一个object实例, 而是一个实例的某个属性, django-rest-framework没有提供该generic class based view. 因此我们需要使用基本的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)

在urls.py中添加对应的路径:

# snippets/urls.py url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),

3. 使用超链接

处理各部件API之间的关系是一件头痛的事. django-rest_framework为我们提供了以下这些方法来表现关系:

使用主键使用超链接使用相关项的slug field使用相关项的默认文本信息将子项显示在母项中其他表现方式

这次, 我们使用超链接的方式来体现user和snippet的关系. 为了实现这一方式, 我们需要改写序列器(serializers), 使用HyperlinkedModelSerializer代替原本的ModelSerializer. HyperlinkedModelSerializer相对于ModelSerializer具有以下不同:

HyperlinkedModelSerializer不会自动包含pk fieldHyperlinkedModelSerializer会自动包括url field关系使用的是HyperlinkedRelatedField而不是PrimaryKeyRelatedField # snippets/serializers.py class SnippetSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.Field(source='owner.username') highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html') class Meta: model = Snippet fields = ('url', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style') class UserSerializer(serializers.HyperlinkedModelSerializer): snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail') class Meta: model = User fields = ('url', 'username', 'snippets')

注意, 我们同时添加了 “highlight” field, 它与url field使用的一样, 是HyperlinkedRelatedField, 但指向的是snippet-highlight url而不是snippet-detail url.

由于我们在url中包含了格式信息, 我们使用format=’html’参数为highlight指定.html后缀.

4. 为url添加name

编辑snippets/urls.py如下:

# snippets/urls.py # API 路径 urlpatterns = format_suffix_patterns(patterns('snippets.views', url(r'^$', 'api_root'), url(r'^snippets/$', views.SnippetList.as_view(), name='snippet-list'), url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view(), name='snippet-detail'), url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view(), name='snippet-highlight'), url(r'^users/$', views.UserList.as_view(), name='user-list'), url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view(), name='user-detail') )) # 可浏览式登录API urlpatterns += patterns('', url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), )

5. 分页

如果数据库中的数据达到一定程度, 那么用户使用api时可能会返回大量数据, 因此, 我们最好使用分页功能:

我们可以使用django-rest-framework自带的设置选项, 使list自动使用分页:

# tutorial/settings.py REST_FRAMEWORK = { 'PAGINATE_BY': 10 }

6. 测试

现在可以使用之前提到的方法测试我们的API了, 可以在/snippets/中看到, 原先的id已经被url代替, url和highlight field都采用超链接的形式.

 

原文链接: http://www.weiguda.com/blog/23/

转载于:https://www.cnblogs.com/leo23/p/5051919.html


最新回复(0)