DRF(Django Rest Framework)
환경 구성
Python, VSCode, Postman, django-rest-framework
$ python -m venv venv # venv 현재 경로에 설치(프로젝트 폴더 생성 후 해야함)
$ venv\Scripts\activate # 입력 시 (venv)c: ... > 형태로 바뀜
$ pip install django
$ pip install djangorestframework
requierments.txt 패키지 관리
$ pip freeze > requirements.txt # 현재 패키지들 텍스트 파일로 저장(패키지 추가할때마다 해줘야함)
$ pip install -r requirements.txt # 텍스트 파일에 저장된 패키지들 install
프로젝트 구조 생성
$ django-admin startproject DRF_study
$ python manage.py startapp user
기본 세팅 - INSTALLED_APP 추가 작성, REST_FRAMEWORK 복붙
# settings.py
INSTALLED_APP = [
...,
'rest_framework',
'user',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [ # 기본적인 view 접근 권한 지정
'rest_framework.permissions.AllowAny'
],
'DEFAULT_AUTHENTICATION_CLASSES': [ # session 혹은 token을 인증 할 클래스 설정
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
],
'DEFAULT_PARSER_CLASSES': [ # request.data 속성에 액세스 할 때 사용되는 파서 지정
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
]
}
DB 모델링 **OPTIONS
- fk에서 사용되는 on_delete에는 여러 속성들이 있으며, 상황에 맞게 사용해야 한다.
- CASCADE : FK로 참조하는 레코드가 삭제 될 경우 해당 레코드를 삭제한다.
- SET_NULL : FK 필드의 값을 Null로 변경해준다. null=True가 정의되어 있어야 사용 가능하다.
- PROTECT : 해당 레코드가 삭제되지 않도록 보호해준다.
- SET_DEFAULT : FK 필드의 값을 default로 변경해준다. default=””가 정의되어 있어야 사용 가능하다.
- SET() : FK 필드의 값을 SET에 설정된 함수를 통해 원하는 값으로 변경할 수 있다.
- DO_NOTHING : 아무런 동작을 하지 않는다. 참조 관계의 무결성이 손상될 수 있기 때문에 권장하지 않는다.
- DateField와 DateTimeField는 default 값을 여러 형태로 지정할 수 있다.
- default = $date : 지정한 값을 기본 값으로 설정한다.
- auto_now_add = True : 레코드가 생성될 때의 date를 기준으로 값을 지정한다.
- auto_now = True : 레코드가 save()될 때마다 갱신된다.
REST API
-> 두 컴퓨터 시스템이 인터넷을 통해 정보를 안전하게 교환하기 위해 사용하는 인터페이스입니다.
http method 종류 - get, post, put, delete
FBV : Function Base View
# user/views.py
def user_view(request):
if request.method == "GET":
...
CBV : Class Base View -
반드시 첫째줄에 있는 APIView를 import 받아와야한다!
클래스 생성 시 APIView상속받아 클래스를 만들면 get, post, put, delete 메서드가 정의 되어있어
해당 메서드를 오버라이딩해서 사용해야 http method 요청에따라 코드를 실행 할 수 있도록 할 수 있다.
# user/views.py
from rest_framework.view import APIView
from rest_framework import permissions
class UserView(APIView):
permission_classes = [permissions.AllowAny] # 누구나 view 조회 가능
def get(self, request):
return Response({'message': 'get method!!'})
def post(self, request):
return Response({'message': 'post method!!'})
def put(self, request):
return Response({'message': 'put method!!'})
def delete(self, request):
return Response({'message': 'delete method!!'})
POSTMAN
collection 을 만들고 각각의 요청들을 생성 및 저장해두고 여러가지 설정 하여 요청을 보내보며 테스트 가능함
요청 보낼 http mehtod 지정 후 보낼 url 그리고 Body에 raw > JSON 데이터로 작성해서 Send 눌리면 Request 보내짐
이대로 보내게되면 django CSRF_middleware에서 걸린다
csrf_token 에러 발생시 Test 부분에 아래 코드 추가하고 Headers에 X-CSRFToken 직접 적어서 보내주면된다.
var xsrfCookie = postman.getResponseCookie("csrftoken");
postman.setGlobalVariable('csrftoken', xsrfCookie.value);
자주 사용 되는 ORM
objects.get은 1개의 object만 리턴되기때문에 없을 경우 DoesNotExist Exception이 발생되고
여러개면 MultipleObjectsReturned Exception이 발생된다!
# objects.get에서 객체가 존재하지 않을 경우 DoesNotExist Exception 발생
# objects.get에서 결과 값이 여러개의 객체를 가져 올 경우 MultipleObjectsReturned Exception 발생
try:
Model.objects.get(id=obj_id)
except Model.DoesNotExist:
# some event
return Response("존재하지 않는 오브젝트입니다.")
except MultipleObjectsReturned:
# some event
return Response("여러개의 오브젝트가 리턴되었습니다.")
order_by(기준이 되는 레코드) 기본 오름차순
Model.objects.all().order_by("join_date")
# -join_date처럼 "-"를 붙이면 역순으로 정렬(내림차순)
Model.objects.all().order_by("-join_date")
# .order_by("?")사용시 무작위 셔플
Model.objects.all().order_by("?")
여러가지 값 추출 방법
# queryset에서 첫번째 object를 가져옴. all()[0]과 동일
Model.objects.all().first()
# queryset에서 해당하는 값만 빼서 가져옴
Model.objects.all().exclude(user=user)
# 지정된 행의 레코드 값이 중복 될 경우 제거
result = Model.objects.filter(user=user).values('취미').distinct()
# queryset으로 object를 return하는게 아닌 list안의 dict 형태로 return
Model.objects.filter(user=user).values()
# 값들을 리스트하나에 담아 return flat을 줄 경우 하나에 다 담음
Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>
# Foriegn key관계, OneToOne 관계들 끼리에서 DB 성능 상승을 위해 사용하면 좋은 코드
class City: ...
class Person: hometown = ForeignKey(City,...
class Book: author = ForeignKey(Person,...
b = Book.objects.select_related('author__hometown').get(id=4)
p = b.author # Doesn't hit the database.
c = p.hometown # Doesn't hit the database.
# ManyToMany 관계들 끼리에서 DB 성능 상승을 위해 사용하면 좋은 코드
>>> Pizza.objects.all()
["Hawaiian (ham, pineapple)", "Seafood (prawns, smoked salmon)"...
이것의 문제는 요청할 때마다 Pizza.__str__()에서 self.toppings.all()데이터베이스를 쿼리해야 하므로
Pizza 의 모든Pizza.objects.all() 항목에 대해 Toppings 테이블에서 쿼리를 실행한다는 것입니다.
다음 을 사용하여 쿼리를 2개로 줄일 수 있습니다 prefetch_related.
>>> Pizza.objects.all().prefetch_related('toppings')
# 입력한 object가 존재 할 경우 해당 object를 가져오고, 존재하지 않을 경우 새로 생성
object, created = Model.objects.get_or_create(
field1="value1",
field2="value2",
)
if created:
# created event
else:
# already exist event
'회고록(TIL&WIL)' 카테고리의 다른 글
TIL 2022.06.21 DRF/ Permissions, django admin 심화, ORM심화 (0) | 2022.06.21 |
---|---|
WIL 2022.06.20 DRF/ Custom User, login/out, 역참조, Serializer (0) | 2022.06.21 |
TIL 2022.06.15 django 특강, TODAY_LUNCH Project Refectoring (0) | 2022.06.15 |
TIL 2022.06.14 TODAY_LUNCH (KPT 회고) (0) | 2022.06.14 |
TIL 2022.06.13 TODAY_LUNCH (bug_fix, refectoring, README) (0) | 2022.06.13 |