django rest framework快速入門第五章 關(guān)系和超鏈接API

第五章 關(guān)系與超鏈接API

寫在前面:
本文翻譯于django rest framework官方文檔,由于網(wǎng)上大多數(shù)django rest framework中文翻譯文檔都有較為多的刪減行為然磷,筆者在學(xué)習(xí)的時(shí)候就覺得不是太方便郑趁,故筆者將官方文檔較為完善的為大家翻譯下,僅供大家學(xué)習(xí)參考姿搜。

由于筆者文筆有限寡润,若有寫得不當(dāng)之處,敬請各位同仁指出舅柜;若涉及到侵權(quán)梭纹,請聯(lián)系筆者,筆者將立即刪除致份。

現(xiàn)在变抽,我們的API中的關(guān)系通過使用主鍵來表示,在教程的這一部分中知举,我們將通過使用超鏈接來改善關(guān)系的內(nèi)聚性和可發(fā)現(xiàn)性瞬沦。

1. 為我們的API創(chuàng)建一個(gè)根路徑

現(xiàn)在我們的userssnippets都配上了路徑了,但是我們沒有一個(gè)單個(gè)的API的進(jìn)入點(diǎn)雇锡。要?jiǎng)?chuàng)建一個(gè)逛钻,我們可以在一個(gè)常規(guī)的基于函數(shù)的視圖和我們前面介紹的@api_view裝飾器。我們現(xiàn)在將在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 Frameworkreverse函數(shù)來返回完全限定的URL立肘;第二边坤,URL Patterns由便捷的模式來標(biāo)識。

我們現(xiàn)在將我們新建的視圖添加到URL Conf中谅年,我們現(xiàn)在在snippets/urls.py中為我們的API根目錄添加一個(gè)新的URL Conf

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

2. 超鏈接我們的API

處理外鍵之間的關(guān)系是Web API設(shè)計(jì)的一個(gè)更具挑戰(zhàn)性的方面茧痒,我們可以選擇多種不同的方式來表示關(guān)系。

  • 使用主鍵
  • 使用實(shí)體之間的超鏈接
  • 在相關(guān)實(shí)體上使用唯一識別的slug字段
  • 使用相關(guān)實(shí)體的默認(rèn)的字符串表現(xiàn)形式
  • 將相關(guān)實(shí)體嵌套在父表示中
  • 一些其他的自定義表示

REST Framework支持所有的這些格式融蹂,并且可以跨前或反向關(guān)系來應(yīng)用他們旺订,或者將他們應(yīng)用于諸如通用外鍵的自定義管理器弄企。

我們現(xiàn)在在實(shí)體間使用超鏈接的樣式,為了這樣做区拳,我們需要修改我們的序列化器以擴(kuò)展HyperlinkedModelSerializer來代替已存在的ModelSerializer

對于HyperlinkedModelSerializerModelSerial有如下的差別:

  • 默認(rèn)情況下不包含id字段
  • 它包含一個(gè)url字段拘领,使用HyperlinkedIdentityField
  • 關(guān)系使用HyperlinkedIdentityField,而不是PrimaryKeyRelatedField

我們可以輕松的重寫我們現(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')

3. 確保我們的URL Patterns已命名

如果我們要有一個(gè)超鏈接的API约素,我們需要確保我們我們命名了我們的URL Patterns,我們來看看我們需要命名的URL Patterns

  • 指向user-listsnippet-list的我們的API的根
  • 用戶的序列化虛包含一個(gè)引用snippet-detail的字段
  • 默認(rèn)情況下我們的user和snippet的序列化程序包含url字段笆凌,默認(rèn)情況下將引用“{model_name}-detail”圣猎,在這樣的情況下,我們要引用的就是snippet-detailuser-detail

將所有的這些添加到我們的URL Conf之后菩颖,我們的snippets/urls.py文件將是如下的樣子:

from django.conf.urls import url, include
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

# API的路徑
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'^users/$',
        views.UserList.as_view(),
        name='user-list'),
    url(r'^users/(?P<pk>[0-9]+)/$',
        views.UserDetail.as_view(),
        name='user-detail')
])

# 登錄和登出
urlpatterns += [
    url(r'^api-auth/', include('rest_framework.urls',
                               namespace='rest_framework')),
]

4. 添加分頁

user和snippet的列表視圖最終可能會(huì)返回很多實(shí)例样漆,我們希望確保分頁結(jié)果,并允許API客戶端逐步的瀏覽每個(gè)單獨(dú)的頁面

我們可以通過修改我們的 tutorial/settings.py 文件晦闰,將默認(rèn)列表樣式更改為使用和分頁放祟,添加如下的設(shè)置:

REST_FRAMEWORK = {
    "PAGE_SIZE": 10
}

我們可以注意到REST Framework的設(shè)置都命名為單個(gè)的字典設(shè)置,這有助于他們和其他的項(xiàng)目設(shè)置保持分離呻右。

5. 下一步

在下一章跪妥,我們將介紹如何使用ViewSetsRouters來減少構(gòu)建我們的API所需的代碼量。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末声滥,一起剝皮案震驚了整個(gè)濱河市眉撵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌落塑,老刑警劉巖纽疟,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異憾赁,居然都是意外死亡污朽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門龙考,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟆肆,“玉大人,你說我怎么就攤上這事晦款⊙坠Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵缓溅,是天一觀的道長蛇损。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么淤齐? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任束世,我火速辦了婚禮,結(jié)果婚禮上床玻,老公的妹妹穿的比我還像新娘。我一直安慰自己沉帮,他們只是感情好锈死,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著穆壕,像睡著了一般待牵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喇勋,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天缨该,我揣著相機(jī)與錄音,去河邊找鬼川背。 笑死贰拿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的熄云。 我是一名探鬼主播膨更,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缴允!你這毒婦竟也來了荚守?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤练般,失蹤者是張志新(化名)和其女友劉穎矗漾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體薄料,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敞贡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了都办。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫡锌。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖琳钉,靈堂內(nèi)的尸體忽然破棺而出势木,到底是詐尸還是另有隱情,我是刑警寧澤歌懒,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布啦桌,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏甫男。R本人自食惡果不足惜且改,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望板驳。 院中可真熱鬧又跛,春花似錦、人聲如沸若治。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽端幼。三九已至礼烈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間婆跑,已是汗流浹背此熬。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滑进,地道東北人犀忱。 一個(gè)月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像扶关,于是被迫代替她去往敵國和親峡碉。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容