728x90
반응형
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"
}
Snippet 모델 추가 작성
모델에 내용 추가
- models.py의 Snippet 모델에 작성
- User와 연결할 uwner ForeignKey와 하이라이트 추가
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
highlighted = models.TextField()
import 추가
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight
save 메서드 추가
- import 한 메서드들을 이용함
- lexer 이름
- Html 포메터
- 하이라이트
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 = "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().save(*args, **kwargs)
디비 재생성 및 슈퍼유저 추가
rm -f db.sqlite3
rm -r snippets/migrations
python manage.py makemigrations snippets
python manage.py migrate
python manage.py createsuperuser
유저 모델에 엔드포인트 추가
- serializers.py에 UserSerializer 추가
- snippets는 User와 1대 다 매칭 필드로 many=True 옵션을 줌
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']
UserList와 UserDetail을 views.py에 추가
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
urls.py에 users의 엔드포인트 추가
path('users/', views.UserList.as_view()),
path('users/<int:pk>/', views.UserDetail.as_view()),
Snippets을 Users와 연결
perform_create 를 사용해 Serializer 인스턴스에 user를 전달함
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
serializers.py에 ReadOnlyField로 owner를 추가
owner = serializers.ReadOnlyField(source='owner.username')
views에 권한 추가
아래 import추가
from rest_framework import permissions
views.py의 SnippetList와 SnippetDetail에 permission_classes 추가
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
Browsable API에 로그인 추가
urls.py에 아래 import 추가
from django.urls import path, include
- api-auth 추가
urlpatterns += [
path('api-auth/', include('rest_framework.urls')),
]
이제 rest_framework 화면에서 로그인 버튼을 볼 수 있으며 스니펫을 생성할 수 있음
객체 레벨 권한
- permissions.py를 만들고 아래 코드를 작성
- 이제 view에서 api에 커스텀 권한을 추가할 수 있음
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
SnippetDetail의 permission_classes를 아래와 같이 수정
permission_classes = [permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly]
import도 추가
from snippets.permissions import IsOwnerOrReadOnly
API로 인증하기
- BasePermission 인증 클래스를 추가했기 때문에 아래와 같은 화면을 볼 수 있음
- 해당 클래스는 SessionAuthentication과 BasicAuthentication을 포함함
http POST http://127.0.0.1:8000/snippets/ code="print(123)"
{
"detail": "Authentication credentials were not provided."
}
로그인 하고 나면 아래와 같이 생성에 성공하는 것을 볼 수 있음
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"
}
728x90
반응형
'Backend > Django' 카테고리의 다른 글
Django Tutorial 6: ViewSets & Routers (0) | 2024.03.12 |
---|---|
Django Tutorial 5: Relationships & Hyperlinked APIs (0) | 2024.03.12 |
Django Tutorial 3: Class-based Views (0) | 2024.03.10 |
Django Tutorial 2: Requests and Responses (0) | 2024.03.10 |
Django Tutorial 1: Serialization (0) | 2024.03.10 |