APIView -> Generic(APIView + Mixins) -> ViewSet(CRUD 다 가능. URL까지 DefaultRouter로 등록 권장)
실습
가상환경 설정
가상환경 활성화
django와 drf 설치
pip install django
pip install djangorestframework
startproject하고 blog 앱 생성
project / urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path('blog/', include('blog.urls')),
path('api-auth/', include('rest_framework.urls')), # 웹 브라우저에서 로그인이 되게 해줌(test가 용이)
]
blog / urls.py 생성하고 urlpatterns = [] 추가
blog / models.py
from django.db import models
from django.conf import settings
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
마이그레이션 하기
python manage.py makemigrations
python manage.py migrate
blog / serializers.py
# form과 같은 형식
from rest_framework.serializers import ModelSerializer
from .models import Post
from django.contrib.auth import get_user_model
# class AuthorSerializer(ModelSerializer):
# class Meta:
# model = get_user_model()
# fields = ['username', 'email']
class PostSerializer(ModelSerializer):
# author = AuthorSerializer()
class Meta:
model = Post
fields = [
'id',
'author',
'title',
'content',
'created_at',
'updated_at',
# 'contents_len',
]
blog / views.py (viewset사용)
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from .models import Post
from .serializers import PostSerializer
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
viewset의 종류
- viewsets.ReadOnlyModelViewSet(list, detail)
- viewsets.ModelViewSet(list, create, detail, update, delete)
아래 모든 APIView 코드가 viewset 3줄로 해결
class BooksAPI(APIView):
def get(self, request):
books = Book.objecst.all()
serializer = BookeSerializer(books, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
serializer = BookeSerializer(books, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request):
books = Book.objects.all()
books.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class BookAPI(APIView):
def get(self, request, id):
book = get.object_or_404(Book, bid=id)
serializer = BookSerializer(book)
return Response(serializer.data, status=status.HTTP_200_OK)
blog / urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register('post', views.PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
runserver을 한 후, 테스트
postman이나 thunder client로도 테스트
인증 구현
settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'user': '1000/day', # 1000번의 요청을 하루에 할 수 있음
# 비인증 요청 거부는 views.py에서 처리
}
}
blog / views.py 수정
from rest_framework.viewsets import ModelViewSet
from .models import Post
from .serializers import PostSerializer
from rest_framework.permissions import IsAuthenticated
from .permissions import IsAuthorOrReadOnly
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticated, IsAuthorOrReadOnly] # 로그인된 사용자만 접근 가능, IsAuthorOrReadOnly 구현
blog / permissions.py 생성
from rest_framework import permissions
class IsAuthorOrReadOnly(permissions.BasePermission):
# R은 모두 허용
# C는 로그인 사용자만 허용
# UD는 작성자만 허용
def has_permission(self, request, view):
'''
GET, HEAD, OPTIONS 요청은 인증 여부와 상관없이
항상 True를 리턴
'''
# if request.method in permissions.SAFE_METHODS:
# return True
if request.user and request.user.is_authenticated:
return True
def has_object_permission(self, request, view, obj):
'''
GET, HEAD, OPTIONS 요청은 인증 여부와 상관없이
항상 True를 리턴. 그 외 요청(PUT, DELETE)에 대해서는
작성자에 한해서만 True를 리턴
'''
if request.method in permissions.SAFE_METHODS:
return True
return obj.author == request.user
'Django > DRF' 카테고리의 다른 글
Django 프로젝트(3) - 📖 School Talks (2) | 2024.01.03 |
---|---|
Django 프로젝트(2) - 🎓 AI 지식인 서비스 (0) | 2023.12.02 |
JWT (JSON Web Token) (0) | 2023.11.17 |
DRF CBV와 User토큰 (0) | 2023.10.20 |
DRF 와 마이크로서비스 튜토리얼 (1) | 2023.10.18 |