Django REST framework 學(xué)習(xí)紀(jì)要 Tutorial 5 Relationships & Hyperlinked APIs

目前我們使用主鍵來表示模型之間的關(guān)系。在本章,我們將提高API的凝聚性和可讀性。

為我們API的根節(jié)點(diǎn)創(chuàng)建URL

之前我們給snippetsusers創(chuàng)建了URL接口,但我們沒有一個(gè)根節(jié)點(diǎn)的URL。
在此我們創(chuàng)建一個(gè)簡(jiǎn)單的,基于函數(shù)的views,并為它加上@api_view裝飾器,修改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)
    })

需要注意兩點(diǎn):

  • 我們使用REST框架中的reverse方法來返回完全符合規(guī)則的url
  • url參數(shù)將會(huì)與我們之后在snippets/urls中定義的相同

編寫snippets/urls.py

url(r'^$', views.api_root),

為高亮代碼創(chuàng)建URL

接下來我們需要為高亮代碼提供接口,和其它的接口不同,這個(gè)接口我們需要展現(xiàn)渲染好的HTML頁面,而不是JSON。
REST框架給我們提供了兩種HTML展現(xiàn)形式,一種是使用模板渲染,一種是使用已經(jīng)提前渲染好的HTML,在此我們使用第二種。
另外,我們需要考慮當(dāng)創(chuàng)建代碼高亮的view時(shí),我們沒有現(xiàn)成的類來繼承,因?yàn)槲覀儾皇欠祷貙?duì)象,而是返回對(duì)象的一個(gè)屬性,我們需要重寫父類的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)

編寫snippets/urls.py

url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),

API之間使用超鏈接

在Web API中處理各個(gè)API之間的關(guān)系是一件非常頭疼的事情,通常有以下方法表示關(guān)系:

  • 使用主鍵
  • 在API之間使用超鏈接
  • 在關(guān)聯(lián)API之間使用唯一字段表示
  • 在關(guān)聯(lián)API之間使用默認(rèn)字符串表示
  • 將一個(gè)API嵌套在另一個(gè)API類中
  • 其它

REST框架支持上述所有方法,并且可以應(yīng)用于正向、反向關(guān)系或類似外鍵這類自定義管理項(xiàng)。
在這里我們使用超鏈接來處理之間的關(guān)系,因此我們需要修改serializers,使用HyperlinkedModelSerializer替代原先的ModelSerializer:

  • 默認(rèn)不包含主鍵
  • 使用HyperlinkedRelatedField時(shí),需要在Meta子類的fields中包含``urls`字段
  • 使用HyperlinkedRelatedField來代替PrimaryKeyRelatedField表示關(guā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')

這里在SnippetSerializer中新增了一個(gè)highlight屬性,這個(gè)屬性和url字段類型相同,區(qū)別在于它指向的是snippet-highlight而非snippet-detail
另外,由于我們有.json格式的后綴,我們需要指定highlight字段使用.html來返回相應(yīng)的格式

確保URL都被命名

在此之前我們創(chuàng)建了一些url參數(shù),在此羅列:

  • 根節(jié)點(diǎn)指向了user-listsnippet-list
  • snippet serializer包含了一個(gè)指向snippet-highlight的url的字段
  • user serializer包含了指向snippet-detail的url的字段
  • snippet serializeruser serializer都包含了url字段,這個(gè)字段默認(rèn)指向{model_name}-detail,這里分別是snippet-detailuser-detail

編輯snippet/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')),
]

添加分頁

后面可能會(huì)有很多個(gè)數(shù)據(jù)產(chǎn)生,我們需要對(duì)返回結(jié)果進(jìn)行分頁,修改tutorial/settings.py

REST_FRAMEWORK = {
    'PAGE_SIZE': 10
}

注意,所有關(guān)于REST框架的settings都在一個(gè)叫做REST_FRAMEWORK的字典中,這幫助我們與其他的settings分離開來。

關(guān)于

本人是初學(xué)Django REST framework,Django REST framework 學(xué)習(xí)紀(jì)要系列文章是我從官網(wǎng)文檔學(xué)習(xí)后的初步消化成果,如有錯(cuò)誤,歡迎指正。

學(xué)習(xí)用代碼Github倉庫:shelmingsong/django_rest_framework

本文參考的官網(wǎng)文檔:Tutorial 5: Relationships & Hyperlinked APIs

博客更新地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容