目前咱們的API中的關係用主鍵表示。在本教程的這一部分中,咱們將改進API的內聚力和可發現性,而不是使用超連接來進行關係。html
如今咱們有'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仍然缺乏的另外一個顯而易見的事情是代碼突出顯示端點。api
與全部其餘API端點不一樣,咱們不想使用JSON,而只是呈現HTML表示。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)
像往常同樣,咱們須要添加咱們在URLconf中建立的新視圖。咱們將爲咱們的新API根添加一個url模式snippets/urls.py
:url
url(r'^$', views.api_root),
而後添加一個url模式的代碼片斷亮點:spa
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),
處理實體之間的關係是Web API設計中更具挑戰性的方面之一。咱們能夠選擇表明一種關係的一些不一樣的方式:設計
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'
後綴。
若是咱們要有一個超連接的API,咱們須要肯定咱們的URL模式。咱們來看看咱們須要命名的URL模式。
'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的工做方式。
您還能夠看到片斷實例上的「突出顯示」連接,這將使您轉到突出顯示的代碼HTML表示。
接下來咱們將介紹如何使用ViewSets和路由器來減小構建API所需的代碼量。