Django REST FrameWork中文教程5:關係和超連接API

目前咱們的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

Django REST FrameWork 中文教程6: ViewSets&Routers

Django REST FrameWork 中文教程7:模式和客戶端庫

相關文章
相關標籤/搜索