Today I Learned D - 57

손상훈·2022년 11월 18일
0

2주차 4강 데코레이터

예시)

5강 모델 시리얼라이즈를 이용한 CRUD

serializers.py

모델시리얼라이즈를 이용해서 article 데이터를 받아오기

from rest_framework import serializers
from articles.models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = "__all__"

views.py에서 추가 및 수정

from rest_framework.decorators import api_view
from rest_framework.response import Response
from articles.models import Article
from articles.serializers import ArticleSerializer

@api_view(['GET', 'POST'])
def index(request):
    articles = Article.objects.all()
    serializer = ArticleSerializer(articles, many=True)
    return Response(serializer.data)

POST요청

from rest_framework.decorators import api_view
from rest_framework.response import Response
from articles.models import Article
from articles.serializers import ArticleSerializer

@api_view(['GET', 'POST'])
def index(request):
	if request.method == "GET":
    	articles = Article.objects.all()
    	serializer = ArticleSerializer(articles, many=True)
    	return Response(serializer.data)
    elif request.method == "POST":
        serializer = ArticleSerializer(data = request.data)
        if serializer.is_vaild():
        	serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

POST 방식일때는 유효한지 검증단계를 거친 뒤 시리얼라이즈를 save()해줘야 한다.

request.data가 아닌 data = request.data라고 넣어줘야 한다. (궁금함. 왜??)

"title":"제목" 만 넣어주게 되면 이러한 오류가 뜬다.

해결방법은 models.py에서 내용부분 맨뒤에 아래의 값을 넣어줘야 함.
null=True 라는 의미는 DB에서 빈값이여도 되냐는 의미.
blank=True는 검증과정에서 비어있어도 되냐는 의미.

프론트에서 에러를 알려주는 것은 좋지 않다.
개발하는 단계에 있어서는 에러값을 표시해주면 좋지만 실무에서는 좋지않다.
추가적으로 400번대 status값을 넣어주도록 한다.
status를 넣어주려면 from rest_framework import status 입력해준다.


상세페이지 만들기. 'GET'

urls.py
path("<int:id>/", views.article_view, name="article_view"), 추가

views.py
from rest_framework.generics import get_object_or_404

@api_view(['GET','PUT','DELETE'])
def article_view(request, article_id):
if request.method == 'GET':
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article)
return Response(article)

잘못된 url의 article_id가 입력 되면 404에러가 띄우게 하기. (조회를 할 때)
from rest_framework.generics import get_object_or_404 추가
article = Article.objects.get(id=article_id) 이것 외에
article = get_object_or_404(Article, id=article_id) 바꿔주기

수정하기. 'PUT'

urls.py
<int:article_id>/로 변경

view.py에 추가
elif request.method == 'PUT':
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article, data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)

  • 'POST' 와 'GET'의 짬뽕된 형태인데. 시리얼라이즈 부분에 (article, data = request.data)로 해준다. 원래 데이터를 뒤에 데이터로 바꿔준다 라는 의미.

urls.py 수정

"index/" -> "/"
views.index -> views.articleAPI
name = "index" -> 'articleAPI'

view.articleDetailAPI,
삭제하기. 'DELETE'

elif request.method == 'DELETE':
article = get_object_or_404(Article, id=article_id)
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

수정을 할때에는 참고로 따옴표 ' 하나짜리는 작동을 안하기 때문에 꼭 " 두개로 써주도록 한다.


포스트맨!

body 변경 시 'row'와 'JSON' 로 되어있는지 잘 확인하기.

JSON?

클라이언트와 클라이언트, 클라이언트와 서버가 데이터를 주고받을 때 사용하는 형식
그 전에는 댓글을 쓰면 웹페이지가 새로고침되는 번거로움이 있었다.
key,value를 JSON형태로 바꾸는것을 시리얼라이즈라고 한다.
Parse = 데이터의 의미 해석

6강 Swagger

사이트를 들어왔을 때 한눈에 API를 볼 수 있게 끔 자동으로 만들어줌.
drf-yasg를 이용하면 됨. 공식문서참조.
pip install drf-yasg 패키지 추가했으면 pip freeze > requirements.txt

INSTALLED_APPS = [
   'django.contrib.staticfiles',  # required for serving swagger ui's css/js files
   'drf_yasg',
]

urls.py에서

from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
   openapi.Info(
      title="Snippets API",
      default_version='v1',
      description="Test description",
      terms_of_service="https://www.google.com/policies/terms/",
      contact=openapi.Contact(email="contact@snippets.local"),
      license=openapi.License(name="BSD License"),
   ),
   public=True,
   permission_classes=[permissions.AllowAny],
)

urlpatterns = [
   re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
   re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
   re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),

]

추가적으로 import에 include 옆에 re_path 넣어주기


7강 클래스형 뷰 Class based views

from rest_framework.views import APIView

공식문서 class list

class SnippetList(APIView):
    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)
    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

urls.py 수정

path('', view.ArticleList.as_view(), name="index"),

  • .as_view()가 추가된 것을 볼 수 있음.

상세페이지 수정

class SnippetDetail(APIView):
    def get_object(self, pk):
        try:
            return Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            raise Http404
    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)    
    def put(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk, format=None):
        snippet = self.get_object(pk)
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
  • get_object_404를 쓰고 있기 때문에 def get_object(self,pk)는 필요없음.
    pk부분은 article_id로 변경.
    put 부분에 에러코드가 추가되어있는데 else로 나눠줘도 된다.

  • from drf_yasg_utils import swagger_auto_schema 추가

  • 명시한 class 바로 윗줄에 @swagger_auto_schema(request_body=ArticleSerailzer)를 해주면 자세한 명세서를 띄울수 있다.


3주차 회원기능

drf jwt 서비스 종료되어 simple jwt 공식문서를 이용.
simple jwt 여기로

패키지설치 (이후 freeze 해주기)

  • pip install djangorestframework-simplejwt

settings.py

REST_FRAMEWORK = {   
    'DEFAULT_AUTHENTICATION_CLASSES': (        
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
    
}

urls.py

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

users 앱폴더 생성
python manage.py startapp users

settings.py
users 앱 추가.
rest_framework_simlejwt 앱 추가.

urls.py
path("users/", include("users.urls")),

token 방식을 drf에 적용시키기 (web token방식)

drf jwt사용하기

profile
< 코린이의 코딩모험기 >

0개의 댓글

관련 채용 정보