[DRFチュートリアル]4.Authentication & Permissions
15259 ワード
コードクリップを変更または削除できるようになりました.
そこで、以下の内容を追加します.コードクリップにcreatorを追加
snippet を作成できるのは、の認証を受けたユーザーのみです.
このフラグメントを変更、削除できるのは creatorのみです.
認証されていないリクエストはread-only です.
所有者をモデルに追加
serializers.pyにプレイヤーを追加します.
観点もあります.pyを変更します.read-onlyビューのみを使用するにはgenericのListAPIビューとRetrieveAPIビューを使用します.
コードクリップがまだ作成されていない場合は、userには関連付けられません.userは自動的にシーケンス化されていませんが、requestの属性として入力されます.
snippetビューにあります.perform create()メソッドを上書きすることで解決できます.これにより、インスタンスの格納方法を管理し、要求された情報を明確にすることができます.
SnipetListビュークラスに追加します.
Serializerの変更
snippetが作成したユーザーに接続されました.これをSnippetSerializerに反映します.Metaクラスにも追加されます.
ReadOnlyFieldはCharFieldやBooleanFieldとは異なり、タイプのないクラスです.常にread-onlyであり、シーケンス化に使用されますが、モデルインスタンスを逆シーケンス化するときに変更するには使用されません.ここではCharField(read only=True)で代用することができます.
Viewsに必要な権限の設定
SnipetListとSnipetDetailの両方を追加します.
認証されたプレイヤーは読むことと書くことができます.そうしないと読むしかありません.
プロジェクトのルートurls.pyに追加します.
コードクリップは誰にでも見られるようにしたいのですが、生成したユーザーのみを修正、削除します.
custom permissionのためにsnippetアプリケーションpermissionに向かいます.pyを生成します.
以前のようにお願いすると、エラーが発生します.
そこで、以下の内容を追加します.
snippet
このフラグメントを変更、削除できるのは
認証されていないリクエストはread-only
所有者をモデルに追加
# snippets/models.py
class Snippet(models.Model):
"""생략"""
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
highlighted = models.TextField()
"""생략"""
また、モデルの保存時にハイライト表示フィールドを追加# snippets/models.py
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight
class Snippet(models.Model):
"""생략"""
def save(self, *args, **kwargs):
lexer = get_lexer_by_name(self.language)
linenos = 'table' if self.linenos else False
options = {'title': self.title} if self.title else {}
formatter = HtmlFormatter(style=self.style, linenos=linenos,
full=True, **options)
self.highlighted = highlight(self.code, lexer, formatter)
super(Snippet, self).save(*args, **kwargs)
"""생략"""
通常、DBテーブルを変更するにはcreate移行が必要ですが、このチュートリアルの目的でDBを削除して再生成します.rm -f db.sqlite3
rm -r snippets/migrations
python manage.py makemigrations snippets
python manage.py migrate
python manage.py createsuperuser
ユーザー・モデルの端点の追加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']
クリップはユーザーモデルとは逆の関係にあるため、ModelSerializerクラスを使用しても自動的に含まれません.したがって、フィールドを明示的に追加する必要があります.観点もあります.pyを変更します.read-onlyビューのみを使用するにはgenericのListAPIビューとRetrieveAPIビューを使用します.
from django.contrib.auth.models import User
from snippets.serializers import UserSerializer
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
最後はsnippets/urlsです.pyを変更します.path('users/', views.UserList.as_view()),
path('users/<int:pk>/', views.UserDetail.as_view()),
Snapetsとユーザーの接続コードクリップがまだ作成されていない場合は、userには関連付けられません.userは自動的にシーケンス化されていませんが、requestの属性として入力されます.
snippetビューにあります.perform create()メソッドを上書きすることで解決できます.これにより、インスタンスの格納方法を管理し、要求された情報を明確にすることができます.
SnipetListビュークラスに追加します.
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
Serializerのcreate()メソッドは、検証されたデータとともに追加のownerフィールドを渡します.Serializerの変更
snippetが作成したユーザーに接続されました.これをSnippetSerializerに反映します.Metaクラスにも追加されます.
owner = serializers.ReadOnlyField(source='owner.username')
sourceパラメータは、フィールドを塗りつぶすために使用する属性を決定します.点記号を使用します.Template言語に似ています.ReadOnlyFieldはCharFieldやBooleanFieldとは異なり、タイプのないクラスです.常にread-onlyであり、シーケンス化に使用されますが、モデルインスタンスを逆シーケンス化するときに変更するには使用されません.ここではCharField(read only=True)で代用することができます.
Viewsに必要な権限の設定
SnipetListとSnipetDetailの両方を追加します.
認証されたプレイヤーは読むことと書くことができます.そうしないと読むしかありません.
from rest_framework import permissions
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
ブラウザへのログインの追加プロジェクトのルートurls.pyに追加します.
from django.urls import path, include
urlpatterns += [
path('api-auth/', include('rest_framework.urls')),
]
オブジェクトレベルの権限の設定コードクリップは誰にでも見られるようにしたいのですが、生成したユーザーのみを修正、削除します.
custom permissionのためにsnippetアプリケーションpermissionに向かいます.pyを生成します.
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
視点.pyに追加します.from snippets.permissions import IsOwnerOrReadOnly
permission_classes = [permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly]
APIによる認証以前のようにお願いすると、エラーが発生します.
http POST http://127.0.0.1:8000/snippets/ code="print(123)"
{
"detail": "Authentication credentials were not provided."
}
以下のようにユーザー名とpasswordを追加すればいいです.http -a admin:password123 POST http://127.0.0.1:8000/snippets/ code="print(789)"
{
"id": 1,
"owner": "admin",
"title": "foo",
"code": "print(789)",
"linenos": false,
"language": "python",
"style": "friendly"
}
Reference
この問題について([DRFチュートリアル]4.Authentication & Permissions), 我々は、より多くの情報をここで見つけました https://velog.io/@leehj8896/DRF-튜토리얼-4.-Authentication-Permissionsテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol