目前我們的API中的關系是用主鍵表示的。我們將通過使用超鏈接來提高我們API的內(nèi)部聯(lián)系。
現(xiàn)在我們有'snippets'和'users'的路徑,但是我們的API沒有一個入口點。我們將使用一個常規(guī)的基于函數(shù)的視圖和我們前面介紹的@api_view裝飾器創(chuàng)建一個。在你的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模式是通過方便的名稱來標識的,我們稍后將在snippets/urls.py中聲明。
我們的API中另一個明顯缺少的是代碼高亮顯示路徑。
與所有其他API路徑不同,我們不想使用JSON,而只是需要HTML表示。REST框架提供了兩種HTML渲染器,一種用于處理使用模板渲染的HTML,另一種用于處理預渲染的HTML。第二個渲染器是我們要用于此路徑的渲染器。
創(chuàng)建代碼高亮視圖時需要考慮的另一件事是,我們沒有可用的具體通用視圖。我們不是返回對象實例,而是返回對象實例的屬性。
不是使用具體的通用視圖,我們將使用基類來表示實例,并創(chuàng)建我們自己的.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中添加我們創(chuàng)建的新視圖。我們將在snippets/urls.py中為我們的新API根路徑添加一個url模式:
url(r'^$', views.api_root),
然后為高亮代碼片段添加一個url模式:
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),
處理好實體之間的關系是Web API設計中更具挑戰(zhàn)性的方面。我們可以選擇幾種不同的方式來代表一種關系:
REST框架支持所有這些方式,并且可以將它們應用于正向或反向關系,也可以在諸如通用外鍵之類的自定義管理器上應用。
在這種情況下,我們希望在實體之間使用超鏈接方式。這樣的話,我們需要修改我們的序列化程序來擴展HyperlinkedModelSerializer而不是現(xiàn)有的ModelSerializer。
HyperlinkedModelSerializer與ModelSerializer有以下區(qū)別:
我們可以輕松地重寫我們現(xiàn)有的序列化程序以使用超鏈接。在你的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模式。
因為我們已經(jīng)包含了格式后綴的URL,例如'.json',我們還需要在highlight字段上指出任何格式后綴的超鏈接,它應該使用'.html'后綴。
如果我們要使用超鏈接的API,那么需要確保為我們的URL模式命名。我們來看看我們需要命名的URL模式。
將所有這些名稱添加到我們的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')
])
# 可瀏覽API的登錄和注銷視圖
urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
]
用戶和代碼片段的列表視圖可能會返回相當多的實例,因此我們希望確保對結(jié)果分頁,并允許API客戶端依次獲取每個單獨的頁面。
我們可以通過稍微修改我們的tutorial/settings.py文件來更改默認列表展示樣式來使用分頁。添加以下設置:
REST_FRAMEWORK = {
'PAGE_SIZE': 10
}
請注意,REST框架中的所有設置都放在一個名為“REST_FRAMEWORK”的字典中,這有助于區(qū)分項目中的其他設置。
如果需要的話,我們也可以自定義分頁風格,但在這個例子中,我們將一直使用默認設置。
如果我們打開瀏覽器并瀏覽我們的API,那么你可以簡單的通過頁面上的超鏈接來了解API。
你還可以看到代碼片段實例上的'highlight'鏈接,它能帶你跳轉(zhuǎn)到高亮顯示的代碼HTML表示。
更多建議: