framework学习之Relationships Hyperlinked APIs

时间:2021-12-12 08:23:38

Relationships & Hyperlinked APIs

 

参考链接:

 

目前我们API中的关系用primary keys展示,这部分我们会通过hyperlinking提高我们API的内聚性和扩展性

 

【1】给API的根节点传建一个端点

在views.py中添加:

from rest_framework.decorators import api_view from rest_framework.response import Response #reverse函数返回完全合格的URLs 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), myLesson:reverse(myLesson-list,request=request,format=format) })

 

【2】为highlighted创建一个端点

和其他API不同的是,我们不用JSON格式,而是用HTML展示,Rest framework提供了两种风格的HTML Render,,一个是使用模板,另一个用pre_rendererd,这里我们使用第二个

因为我们要返回的不是一个类,而是一个属性,所以没有我们能够是用的具体的generic view,所以我们用generics.GenericAPIView并自己创建get方法

 

在views.py中添加:

from rest_framework import renderers class MyLessonHighlight(generics.GenericAPIView): queryset = MyLesson.objects.all() serializer_class = MyLessonSerializer renderer_classes = (renderers.StaticHTMLRenderer,) def get(self,request,*args,**kwargs): myLesson = self.get_object() return Response(myLesson.highlighted)

 

在mylesson中urls.py添加:

url(r^$, views.api_root), url(r^myLesson/(?P<pk>[0-9]+)/highlight/$, views.MyLessonHighlight.as_view()),

 

【3】给API添加超链接

有很多方式可以展示实体间的关系:primary keys, hyperlinking, unique identifying slug field, default string, 或者使两个类继承自一个母体

REST framework 提供了上述所有风格,在此case中我们使用hyperlinked,使用HyperlinkedModelSerializer

HyperlinkedModelSerializer 和 ModelSerializer 的区别:没有id,多了url,用HyperlinkedRelatedField代替PrimaryKeyRelatedField

 

因此我们重写serializers.py

from rest_framework import serializers from myLesson.models import MyLesson from django.contrib.auth.models import User class MyLessonSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.ReadOnlyField(source=owner.username) url = serializers.HyperlinkedIdentityField(view_name="myLesson-detail") highlight = serializers.HyperlinkedIdentityField(view_name=myLesson-highlight,format=html) class Meta: model = MyLesson fields = (url,id,highlight,owner,title,code,linenos,language,style) class UserSerializer(serializers.HyperlinkedModelSerializer): # myLesson = serializers.PrimaryKeyRelatedField(many=True,queryset=MyLesson.objects.all()) myLesson = serializers.HyperlinkedRelatedField(many=True,view_name=myLesson-detail,read_only=True) class Meta: model = User fields = (url,id,username,myLesson)

 

【4】确认URL patterns已经被命名

 

修改myLesson/urls.py:

from django.conf.urls import url,include from myLesson import views from rest_framework.urlpatterns import format_suffix_patterns urlpatterns = [ url(r^$,views.api_root), url(r^users/$,views.UserList.as_view(),name=user-list), url(r^users/(?P<pk>[0-9]+)/$,views.UserDetail.as_view(),name=user-detail), url(r^myLesson/$,views.MyLessonList.as_view(),name=myLesson-list), url(r^myLesson/(?P<pk>[0-9]+)/$,views.MyLessonDetail.as_view(),name=myLesson-detail), url(r^myLesson/(?P<pk>[0-9]+)/highlight/$,views.MyLessonHighlight.as_view(),name=myLesson-highlight),] urlpatterns = format_suffix_patterns(urlpatterns)

 

【5】添加分页

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

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

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

【6】修改bug,按照官网文档的代码写完运行调试,有bug,报错