摘要:未經(jīng)身份驗(yàn)證的請(qǐng)求應(yīng)具有完全只讀訪問權(quán)限。其中一個(gè)字段將用于表示創(chuàng)建代碼段的用戶。唯一的限制是所包含的必須使用命名空間。中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫
目前,我們的API對(duì)誰可以編輯或刪除代碼段沒有任何限制。我們想要一些更高級(jí)的行為,以確保:
代碼段始終與創(chuàng)建者相關(guān)聯(lián)。
只有身份驗(yàn)證的用戶可以創(chuàng)建片段。
只有片段的創(chuàng)建者可以更新或刪除它。
未經(jīng)身份驗(yàn)證的請(qǐng)求應(yīng)具有完全只讀訪問權(quán)限。
將信息添加到我們的模型
我們將對(duì)我們的Snippet模型類進(jìn)行一些更改。首先,我們添加幾個(gè)字段。其中一個(gè)字段將用于表示創(chuàng)建代碼段的用戶。另一個(gè)字段將用于存儲(chǔ)代碼的突出顯示的HTML表示。
將以下兩個(gè)字段添加到Snippet模型中models.py。
owner = models.ForeignKey("auth.User", related_name="snippets", on_delete=models.CASCADE) highlighted = models.TextField()
我們還需要確保在保存模型時(shí),使用pygments代碼突出顯示庫填充突出顯示的字段。
我們需要一些額外的導(dǎo)入:
from pygments.lexers import get_lexer_by_name from pygments.formatters.html import HtmlFormatter from pygments import highlight
現(xiàn)在我們可以.save()在我們的模型類中添加一個(gè)方法:
def save(self, *args, **kwargs): """ Use the `pygments` library to create a highlighted HTML representation of the code snippet. """ lexer = get_lexer_by_name(self.language) linenos = self.linenos and "table" or False options = self.title and {"title": self.title} or {} formatter = HtmlFormatter(style=self.style, linenos=linenos, full=True, **options) self.highlighted = highlight(self.code, lexer, formatter) super(Snippet, self).save(*args, **kwargs)
完成這些工作后,我們需要更新我們的數(shù)據(jù)庫表。通常我們將創(chuàng)建一個(gè)數(shù)據(jù)庫遷移,為了做到這一點(diǎn),但是為了本教程的目的,我們只需刪除數(shù)據(jù)庫并重新開始
rm -f tmp.db db.sqlite3 rm -r snippets/migrations python manage.py makemigrations snippets python manage.py migrate
您可能還需要?jiǎng)?chuàng)建幾個(gè)不同的用戶,以用于測(cè)試API。執(zhí)行此操作的最快方法是使用createsuperuser命令。
python manage.py createsuperuser
為我們的用戶模型添加端點(diǎn)
現(xiàn)在我們有一些用戶可以使用,我們最好將這些用戶的表示添加到我們的API中。創(chuàng)建一個(gè)新的serializer很容易。在serializers.py添加:
from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer): snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all()) class Meta: model = User fields = ("id", "username", "snippets")
因?yàn)樵赨ser模型上"snippets"是一個(gè)反向關(guān)系,所以在使用ModelSerializer該類時(shí)它不會(huì)被默認(rèn)包含,所以我們需要為它添加一個(gè)顯式字段。
我們還會(huì)添加幾個(gè)視圖views.py。我們希望只使用只讀視圖為用戶表示,所以我們將使用ListAPIView和RetrieveAPIView通用的基于類的意見。
from django.contrib.auth.models import User class UserList(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer class UserDetail(generics.RetrieveAPIView): queryset = User.objects.all() serializer_class = UserSerializer
確保也導(dǎo)入U(xiǎn)serSerializer類
from snippets.serializers import UserSerializer
最后,我們需要通過從URL conf引用它們將這些視圖添加到API中。將以下內(nèi)容添加到其中的模式中urls.py。
url(r"^users/$", views.UserList.as_view()), url(r"^users/(?P[0-9]+)/$", views.UserDetail.as_view()),
將片段與用戶關(guān)聯(lián)
現(xiàn)在,如果我們創(chuàng)建了一個(gè)代碼片段,那么將無法將創(chuàng)建該代碼段的用戶與代碼段實(shí)例相關(guān)聯(lián)。用戶不是作為序列化表示的一部分發(fā)送的,而是傳入請(qǐng)求的屬性。
我們處理的方式是覆蓋.perform_create()我們的代碼片段視圖上的方法,這樣我們可以修改實(shí)例保存的管理方式,并處理傳入請(qǐng)求或請(qǐng)求的URL中隱含的任何信息。
在SnippetList視圖類中,添加以下方法:
def perform_create(self, serializer): serializer.save(owner=self.request.user)
create()我們的串行器的方法現(xiàn)在將被傳遞一個(gè)附加"owner"字段,以及請(qǐng)求中驗(yàn)證的數(shù)據(jù)。
更新我們的serializer
現(xiàn)在,這些片段與創(chuàng)建它們的用戶相關(guān)聯(lián),我們更新我們SnippetSerializer來反映這一點(diǎn)。將以下字段添加到序列化器定義中serializers.py:
owner = serializers.ReadOnlyField(source="owner.username")
注意:確保您還添加"owner",到內(nèi)部Meta類的字段列表。
這個(gè)領(lǐng)域正在做一些很有趣的事情。的source哪個(gè)屬性參數(shù)控制用于填充的字段,并且可以在對(duì)串行化實(shí)例的任何屬性點(diǎn)。它也可以采用上面顯示的點(diǎn)劃線,在這種情況下,它將以與Django模板語言一起使用的相似方式遍歷給定的屬性。
我們添加了字段是類型化ReadOnlyField類,相對(duì)于其他類型的字段,如CharField,BooleanField等...類型化ReadOnlyField始終是只讀的,并且將用于序列化表示形式,但不會(huì)被用于更新模型他們被反序列化的實(shí)例。我們也可以CharField(read_only=True)在這里使用。
添加視圖所需的權(quán)限
現(xiàn)在,代碼片段與用戶相關(guān)聯(lián),我們希望確保只有經(jīng)過身份驗(yàn)證的用戶才能創(chuàng)建,更新和刪除代碼段。
REST框架包括許多權(quán)限類,我們可以使用它們來限制誰可以訪問給定的視圖。在這種情況下,我們正在尋找的是IsAuthenticatedOrReadOnly,這將確保經(jīng)過身份驗(yàn)證的請(qǐng)求獲得讀寫訪問權(quán)限,未經(jīng)身份驗(yàn)證的請(qǐng)求將獲得只讀訪問權(quán)限。
首先在視圖模塊中添加以下導(dǎo)入
from rest_framework import permissions
接著,下面的屬性添加到都在SnippetList和SnippetDetail視圖類。
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
添加登錄到Browsable API
如果您打開瀏覽器并導(dǎo)航到目前可瀏覽的API,那么您將發(fā)現(xiàn)無法再創(chuàng)建新的代碼段。為了做到這一點(diǎn),我們需要能夠以用戶身份登錄。
我們可以通過編輯項(xiàng)目級(jí)urls.py文件中的URLconf來添加可瀏覽API使用的登錄視圖。
在文件頂部添加以下導(dǎo)入:
from django.conf.urls import include
并且,在文件末尾,添加一個(gè)模式以包括可瀏覽的API的登錄和注銷視圖。
urlpatterns += [ url(r"^api-auth/", include("rest_framework.urls", namespace="rest_framework")), ]
r"^api-auth/"模式的一部分實(shí)際上可以是您要使用的任何URL。唯一的限制是所包含的URL必須使用"rest_framework"命名空間。在Django 1.9+中,REST框架將設(shè)置命名空間,因此您可以將其刪除。
現(xiàn)在,如果再次打開瀏覽器并刷新頁面,您將在頁面右上角看到一個(gè)“登錄”鏈接。如果您以您之前創(chuàng)建的用戶身份登錄,則可以再次創(chuàng)建代碼段。
創(chuàng)建幾個(gè)代碼片段后,導(dǎo)航到“/ users /”端點(diǎn),并注意到該表示包含每個(gè)用戶的“片段”字段中與每個(gè)用戶相關(guān)聯(lián)的代碼段的列表。
對(duì)象級(jí)權(quán)限
我們希望所有的代碼片段都可以被任何人看到,但也要確保只有創(chuàng)建代碼段的用戶才能更新或刪除它。
要做到這一點(diǎn),我們將需要?jiǎng)?chuàng)建一個(gè)自定義權(quán)限。
在片段應(yīng)用中,創(chuàng)建一個(gè)新文件, permissions.py
from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """ Custom permission to only allow owners of an object to edit it. """ def has_object_permission(self, request, view, obj): # Read permissions are allowed to any request, # so we"ll always allow GET, HEAD or OPTIONS requests. if request.method in permissions.SAFE_METHODS: return True # Write permissions are only allowed to the owner of the snippet. return obj.owner == request.user
現(xiàn)在,我們可以通過編輯視圖類中的permission_classes屬性將該自定義權(quán)限添加到我們的代碼段實(shí)例端點(diǎn)SnippetDetail:
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,)
確保也導(dǎo)入IsOwnerOrReadOnly類。
from snippets.permissions import IsOwnerOrReadOnly
現(xiàn)在,如果再次打開瀏覽器,您會(huì)發(fā)現(xiàn)如果您以與創(chuàng)建代碼段相同的用戶身份登錄,“DELETE”和“PUT”操作只會(huì)顯示在代碼段實(shí)例端點(diǎn)上。
使用API進(jìn)行身份驗(yàn)證
因?yàn)槲覀儸F(xiàn)在有一組API的權(quán)限,如果我們要編輯任何片段,我們需要驗(yàn)證我們的請(qǐng)求。我們還沒有設(shè)置任何身份驗(yàn)證類,所以默認(rèn)值現(xiàn)在被應(yīng)用,哪些是SessionAuthentication和BasicAuthentication。
當(dāng)我們通過Web瀏覽器與API進(jìn)行交互時(shí),我們可以登錄,然后瀏覽器會(huì)話將為請(qǐng)求提供所需的身份驗(yàn)證。
如果我們以編程方式與API交互,我們需要在每個(gè)請(qǐng)求上顯式提供身份驗(yàn)證憑據(jù)。
如果我們嘗試創(chuàng)建一個(gè)沒有驗(yàn)證的代碼段,我們會(huì)收到一個(gè)錯(cuò)誤:
http POST http://127.0.0.1:8000/snippets/ code="print 123" { "detail": "Authentication credentials were not provided." }
我們可以通過包括我們之前創(chuàng)建的一個(gè)用戶的用戶名和密碼來成功提出請(qǐng)求。
http -a tom:password123 POST http://127.0.0.1:8000/snippets/ code="print 789" { "id": 1, "owner": "tom", "title": "foo", "code": "print 789", "linenos": false, "language": "python", "style": "friendly" }
概要
我們現(xiàn)在已經(jīng)在我們的Web API上獲得了一個(gè)相當(dāng)精細(xì)的權(quán)限,并為系統(tǒng)的用戶和他們創(chuàng)建的代碼段提供了終點(diǎn)。
在本教程的第5部分中,我們將介紹如何通過為突出顯示的片段創(chuàng)建一個(gè)HTML端點(diǎn)來將所有內(nèi)容聯(lián)結(jié)在一起,并通過為系統(tǒng)中的關(guān)系使用超鏈接來提高API的凝聚力。
Django REST FrameWork 中文教程1:序列化
Django REST FrameWork 中文教程2:請(qǐng)求和響應(yīng)
Django REST FrameWork 中文教程3:基于類的視圖
Django REST FrameWork 中文教程4:驗(yàn)證和權(quán)限
Django REST FrameWork 中文教程5:關(guān)系和超鏈接API
Django REST FrameWork 中文教程6: ViewSets&Routers
Django REST FrameWork 中文教程7:模式和客戶端庫
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/44458.html
摘要:未經(jīng)身份驗(yàn)證的請(qǐng)求應(yīng)具有完全只讀訪問權(quán)限。其中一個(gè)字段將用于表示創(chuàng)建代碼段的用戶。唯一的限制是所包含的必須使用命名空間。中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 目前,我們的API對(duì)誰可以編輯或刪除代碼段沒有任何限制。我們想要一些更高級(jí)的行為,以確保: 代碼段始終與創(chuàng)建者相關(guān)聯(lián)。 只有身份驗(yàn)證的用戶可以創(chuàng)建...
摘要:未經(jīng)身份驗(yàn)證的請(qǐng)求應(yīng)具有完全只讀訪問權(quán)限。其中一個(gè)字段將用于表示創(chuàng)建代碼段的用戶。唯一的限制是所包含的必須使用命名空間。中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 目前,我們的API對(duì)誰可以編輯或刪除代碼段沒有任何限制。我們想要一些更高級(jí)的行為,以確保: 代碼段始終與創(chuàng)建者相關(guān)聯(lián)。 只有身份驗(yàn)證的用戶可以創(chuàng)建...
摘要:看起來不錯(cuò)再次,它現(xiàn)在仍然非常類似于基于功能的視圖。我們還需要重構(gòu)一下我們使用基于類的視圖。中文文檔目錄中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 我們也可以使用基于類的視圖編寫我們的API視圖,而不是基于函數(shù)的視圖。我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用常用功能,并幫助我們保持代碼DRY。 使用基于類的...
摘要:看起來不錯(cuò)再次,它現(xiàn)在仍然非常類似于基于功能的視圖。我們還需要重構(gòu)一下我們使用基于類的視圖。中文文檔目錄中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 我們也可以使用基于類的視圖編寫我們的API視圖,而不是基于函數(shù)的視圖。我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用常用功能,并幫助我們保持代碼DRY。 使用基于類的...
摘要:看起來不錯(cuò)再次,它現(xiàn)在仍然非常類似于基于功能的視圖。我們還需要重構(gòu)一下我們使用基于類的視圖。中文文檔目錄中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 我們也可以使用基于類的視圖編寫我們的API視圖,而不是基于函數(shù)的視圖。我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用常用功能,并幫助我們保持代碼DRY。 使用基于類的...
閱讀 1598·2021-11-04 16:11
閱讀 3309·2021-09-09 11:33
閱讀 1558·2019-08-30 15:54
閱讀 619·2019-08-30 15:44
閱讀 3174·2019-08-30 15:43
閱讀 2554·2019-08-30 13:06
閱讀 1698·2019-08-29 17:00
閱讀 895·2019-08-29 15:33