저번 글인 CRUD2에서는 models.py 작성을 보았다.
이번에는 views.py에서 POST, GET을 보겠다. 역시나 아래와 같은 모델을 사용한다.
이제 스타벅스에서 마이너한 음료 이름까지 외워버렸다.
제주에만 가서 먹을 수 있는 '제주 쑥떡 크림 프라푸치노', '제주 쑥쑥 라떼'
제주도 가면 꼭 먹고싶다.
참고로 내가 짠 views.py가 효율적인지, 실제로 현업에서 이런 식으로 쓰는지는 정확하지 않다!! 참고만 해주시길 바란다. 한달후에 더 많은 지식이 쌓이고 돌이켜보면 굉장히 부족할 수도 있다고 생각한다.
만약 틀린 부분이 있다면 댓글 꼭 달아주길 바란다.
westarbucks 폴더에 products 라는 app이 있음.
아래는 westarbucks 폴더에서 terminal 에 tree를 입력한 상황:
view는 http request에 맞는 response를 해주어야하는 파이썬 function을 담고 있다.
CRUD1 글에서 썼듯, 드디어 진짜로 CRUD를 할 차례이다!
Create - POST
Read - GET
Update - PATCH
Delete - DELETE
import json
: json은 파이썬의 built-in module이다. json 데이터를 읽고 해석하는 역할을 한다. 이게 없다면 http request의 데이터를 읽어내지 못한다!
from django.http import JsonResponse
: JsonResponse 는 HttpResponse라는 class의 subclass(하위 클래스)이다. django.http 는 module이다. json 데이터를 리턴하기 쉽게 만들어주는 클래스이다.
from django.views import View
: View란 역시 class이고, django.views는 module이다. views.py 안에 있는 모든 클래스들이 View를 inherit 해야하므로 (상속 받아야하므로) 반드시 import 해주어야한다.
from products.models import Menu, Category, Drink, Allergy, Allergy_drink, Image, Nutrition
: products안의 models.py에서 뒤에 있는 클래스를 import하라는 뜻이다.
나는 위와 같이 http -v post 요청을 보내는 것으로 생각을 했다.
post 함수를 실행시키기 전에 데이터를 어떤 형식으로 request를 요청할지 생각해볼 수 있다.
- allergy는 여러개가 있을 수 있기 때문에 list 형식
- nutrition은 dictionary 형식
- 참고로 위의 "", '', : 하나하나 다 신경 써야한다. 문법이다! "" 대신에 '' 쓰면 에러난다. 개복치이기 때문이다
이 사이트 http request 보내시는 분은 꼭 읽으시길!
https://devhints.io/httpie 에서 http request 보낼 때 쓰이는 문법을 엿볼 수 있다
post는 class ProductsView(View)
아래에 def post(self, request)
라는 함수를 만들어 구현할 것이다.
data = json.loads(request.body)
: data라는 변수에 request.body에 있는 것을 받는다는 것이다.
받은 데이터는 아래와 같이 여러 변수에 담아둔다.
이건 정말 꿀팁인데, 그냥 objects.create 가 아니고 get_or_create를 하면 없으면 만들고 있으면 연결시켜줄 수 있다.
근데 한가지 주의할 점이 있다.
위의 소스코드를 보면 menu = menu[0], category = category[0]이라고 써있다. 왜 이렇게 썼을까??
데이터베이스에 이름이 '럼 샷 코르타도'이고 category_id 가 5 (에스프레소)인 drink가 이미 존재하는 상황이다. 이런 상황에서, 아래와 같이 파이썬 쉘을 켜고 drink1이라는 변수에 이 Drink의 instance를 담아보면?
drink1이 (<Drink: Drink object (7)>, False)로 나오는 것을 확인할 수 있다.
False: 이미 존재한다
True: 존재하지 않는다. 만들어준다.
get 함수도 class ProductsView(View)
안에 만들어주었다.
post 요청을 보냈을 때처럼 리턴받고 싶었던 데이터의 형식을 생각해보았다.
- 전체는 dictionary 형태일것
- "allergy" : list 형태
- "nutrition" : dictionary 형태
일단 drinks 라는 함수에 데이터베이스에 있는 모든 Drink instance, 즉 object 를 담았다.
그리고 반환할 결과인 list 형태의 result를 만들었다.
각각의 drink에 대해서 result 가 하나씩 있어야하므로 for drink in drinks:
로 for loop을 돌렸다.
allergies라는 변수에 그 drink가 가진 알러지를 담은 모든 객체를 담았다. 고로 allergies 는 queryset인 상태이다.
위의 소스코드에서 일부분만 보자.
nutrition 을 dictionary 형태로 내보내기 위해 나는 일단
- 해당하는 drink의 nutrition object 을 filter를 통해 받았다. -> queryset 이다.
- 그 queryset의 .values()를 쓰면 또 queryset이 나온다.
- 그 queryset의 0번째 인덱스는 우리가 원하는 딕셔너리 형태이다.
아래는 파이썬 shell에서의 실험 결과이다.
post에서:
있으면 안 만들고, 없으면 만들고 싶다면 get_or_create()를 쓰자
get_or_create()는 tuple을 리턴한다.
get에서:
리턴 받을 데이터의 형태를 생각하자. allergy는 list로, nutrition은 dictionary로 받자.
filter()는 queryset을 리턴한다.
최대한 알기 쉽게 쓰려고 했는데도 나의 글쓰기 솜씨는 한없이 부족한 것 같다.
다음 기수의 위코드분들이 이걸 보고 꼭 도움 받았으면 좋겠다.
위코드 멘토님들은 1을 알려주면 10을 해보기를 바라신다. 그래서 나도 열심히 굴렀다. 구르고 구르면서 동기들과 상의해가면서 이런 함수를 써야하는구나, 이런 식으로 코드를 짜야하는구나 알았다.
물론 내 코드가 정답일 것 같지는 않지만, 정답에 60프로라도 가깝다면 진짜 누군가에게 도움이 되기를 바란다.
누군가에게 도움이 되고 싶던 호진이가... 이만 총총....
엄청난 도움이 될것입니다 >< 잘 읽었습니다~~~ ❤️