目前咱們的API中的關係經過使用主鍵來表示。在本教程的這一部分中,咱們將改進API的內聚力和可發現性,而不是使用超連接來進行關係。html
爲咱們的API的根建立一個端點
如今咱們有'snippets'和'users'的端點,可是咱們的API沒有一個入口點。要建立一個,咱們將使用一個常規的基於函數的視圖和@api_view咱們以前介紹的裝飾器。在你的snippets/views.py添加:django
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.py。json
爲突出顯示的片斷建立端點
咱們的pastebin API中仍然缺乏的另外一個明顯的事情是代碼突出顯示端點。segmentfault
與全部其餘API端點不一樣,咱們不想使用JSON,而只是呈現HTML表示。REST框架提供了兩種HTML渲染器樣式,一種用於處理使用模板呈現的HTML,另外一種用於處理預呈現的HTML。第二個渲染器是咱們要用於此端點的渲染器。api
在建立代碼高亮度視圖時,咱們須要考慮的另外一件事是,咱們可使用現有的具體通用視圖。咱們不是返回一個對象實例,而是一個對象實例的屬性。瀏覽器
而不是使用具體的通用視圖,咱們將使用基類來表示實例,並建立咱們本身的.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)
像往常同樣,咱們須要添加咱們在URLconf中建立的新視圖。咱們將爲咱們的新API根添加一個url模式snippets/urls.py:函數
url(r'^$', views.api_root),
而後爲代碼片斷添加一個url模式:post
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),
超連接咱們的API
處理實體之間的關係是Web API設計中更具挑戰性的方面之一。咱們能夠選擇表明關係的一些不一樣的方式:url
使用主鍵
在實體之間使用超連接。
在相關實體上使用惟一的標識字段。
使用相關實體的默認字符串表示形式。
將相關實體嵌套在父表示內。
一些其餘自定義表示。
REST框架支持全部這些樣式,而且能夠將它們應用於正向或反向關係,也能夠在諸如通用外鍵之類的自定義管理器上應用。
在這種狀況下,咱們但願在實體之間使用超連接樣式。爲了這樣作,咱們將修改咱們的序列化程序來擴展HyperlinkedModelSerializer而不是現有的ModelSerializer。
在HyperlinkedModelSerializer有如下區別ModelSerializer:
id默認狀況下不包括該字段。
它包括一個url字段,使用HyperlinkedIdentityField。
關係使用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-detail'url模式。
由於咱們已經包括格式後綴的URL '.json',因此咱們還須要在highlight字段上指出任何格式後綴的超連接它應該使用'.html'後綴。
確保咱們的URL模式被命名
若是咱們要有一個超連接的API,咱們須要確保咱們命名咱們的URL模式。咱們來看看咱們須要命名的URL模式。
咱們的API的根源是指'user-list'和'snippet-list'。
咱們的片斷序列化程序包括一個引用的字段'snippet-highlight'。
咱們的用戶串行器包括一個引用的字段'snippet-detail'。
咱們的片斷和用戶序列化程序包括'url'默認狀況下將引用的字段,'{model_name}-detail'在這種狀況下將是'snippet-detail'和'user-detail'。
將全部這些名字添加到咱們的URLconf中後,咱們的最終snippets/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<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') ]) # Login and logout views for the browsable API urlpatterns += [ url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), ]
添加分頁
用戶和代碼段的列表視圖可能會返回至關多的實例,所以咱們但願確保分頁結果,並容許API客戶端逐步瀏覽每一個單獨的頁面。
咱們能夠經過tutorial/settings.py稍微修改咱們的文件來更改默認列表樣式來使用分頁。添加如下設置:
REST_FRAMEWORK = { 'PAGE_SIZE': 10 }
請注意,REST框架中的設置都命名爲單個字典設置,名爲「REST_FRAMEWORK」,這有助於保持與其餘項目設置的良好分離。
咱們也能夠自定義分頁風格,若是咱們也須要,但在這種狀況下,咱們將堅持默認。
瀏覽API
若是咱們打開瀏覽器並導航到可瀏覽的API,那麼您將發現您如今能夠經過如下連接瞭解API的方法。
您還能夠在代碼段實例上看到「突出顯示」連接,這將使您轉到突出顯示的代碼HTML表示。
在本教程的第6部分中,咱們將介紹如何使用ViewSets和路由器來減小構建API所需的代碼量。
Django REST FrameWork中文文檔目錄:
Django REST FrameWork 中文教程1:序列化
Django REST FrameWork 中文教程2:請求和響應
Django REST FrameWork 中文教程3:基於類的視圖
Django REST FrameWork 中文教程4:驗證和權限
Django REST FrameWork 中文教程5:關係和超連接API