앞서 공부한 http 통신을 이용한 data 처리를 과제용 프로젝트인 westarbucks
에 적용시키기로 한다!
지금은 따라치는것 하지 않고!! 이해하고, 내 손으로 쳐보자!
http통신을 통해 client와 server가 통신을 하게 되면 client 입장에서는 data 를 get
하느냐, 입력받은 data를 post
하느냐 둘중 하나를 할 것이다.
때문에 server 입장에서는 client가 get을 요청했을땐 READ
를 / post를 요청했을땐 CREATE
를 진행하는 것이다!
즉, create를 하기 위해서는 post 메소드
를, read 하기 위해서는 get 메소드
를 사용한다.
코드 작성 순서는 다음과 같다!!
1. 함수 작성하기 (app dir에서 views.py 에 작성한다)
2. client로부터 request를 받았을때 이를 처리할 전체적인 url 지정하기 (즉 프로젝트의 urls.py 를 작성한다.)
3. 프로젝트의 url이 작동시킬 app의 url (중간 url) 작성하기
client로부터 request가 왔을때의 흐름은 다음과 같다!! Request target
1. client로부터 온 request를 가장 먼저 받는 프로젝트의 url => 프로젝트의 urls.py 에서 처리
2. 프로젝트의 urls.py 의 처리로 해당되는 app의 url로 전달됨
3. url 경로로 지정된 app의 views.py 에 지정된 함수가 실행됨
흐름을 파악하면 urls.py 의 설정들이 왜 그렇게 지정되는지 이해하는데 도움이 된다!!
read 하기!! 즉 서버에서 클라이언트로 / 백엔드에서 프론트엔드로 data를 갖고 오는것
이다 .때문에 http의 get 메소드
가 사용된다!
그런데.. 현재 products table 에 가격에 대한 column이 없다. ^^.... 만든다. 나. column
그리고 products table에서 description column은 주석처리 하겠다.. 길기만 하고 쓸데가 없어 ??? 주석처리해도 안사라지넹;; 일단 그냥 한다.
price는 default 로 다 2000을 줌!
그냥 계속 이 터미널 켜둔다. (작업은 다른 터미널에서!)
최종적으로 url의 경로를 타고 왔을때 products 라는 앱 안에서 생성된 product 테이블의 이름, 가격, 카테고리이름 에 대해서 출력이 되어야 한다!
import json
from django.http import JsonResponse
from django.views import View
from products.models import Menu, Category, Product
class ProductsView(View):
def get(self, request):
products = Product.objects.all()
results = []
for product in products:
results.append({
"menu" : product.category.menu.name,
"category" : product.category.name,
"product" : product.name
})
return JsonResponse({'results':results}, status=200)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('products', include('products.urls'))
]
이러게 작성하고 나면 runserver 중인 터미널에서
ModuleNotFoundError: No module named 'products.urls'
라는 에러가 뜬다. 아직 app의 url을 지정하지 않아서 그래.. 기다려줘..
from django.urls import path
from products.views import ProductsView
urlpatterns = [
path('', ProductsView.as_view())
]
그리고... models.py 에 클래스명 진짜 잘지어야됨... views.py에 적는데 자꾸~~~ ImportError: cannot import name
뜬다. 이름 몇번 확인 필요~
read 하기 위해 http 에서 보내는 request는 다음과 같다.
http -v GET 127.0.0.1:8000/products
AttributeError: 'Categories' object has no attribute 'menu'
😃 ....
문제의 Categories 클래스 상태
class Categories(models.Model):
Menu = models.ForeignKey('Menu', on_delete=models.CASCADE)
name = models.CharField(max_length=50)
def __str__(self):
return f'{self.name}'
class Meta:
db_table = 'Categories'
attribute를 보면 menu가 아니라 Menu 이다..
그리고 클래스 명도 복수임;
이제 맞춰 views.py 에서 코드를 수정해준다.
runserver 중인 터미널
request 입력한 터미널
출력된거는 보면 category / menu / product 이다... 과제에서 원한건 음료의 이름 / 가격 / 카테고리 이름
이다.
import json
from django.http import JsonResponse
from django.views import View
from products.models import Menu, Categories, Product
class ProductsView(View):
def get(self, request):
products = Product.objects.all()
results = []
for product in products:
results.append({
"product" : product.name,
"price" : product.price,
"category" : product.category.name,
})
return JsonResponse({'results':results}, status=200)
참고로 chrom 에서 localhost:8000/products
를 치면 이렇게 뜬다.
이게 Json의 text 형식이다... 못알아 본다 그래서 Json.loads
해주는 것이다.
그래서 내가 views.py 에서 아무리 순서를 바꿔도 어차피 read는 알파벳 순으로 되더라;!
create 한다는 것은 프론트로받은 정보를 database에 저장하는것! 즉, 포스팅
의 개념이다. 따라서 http의 post 메소드
를 사용한다.
그리고, http로부터 받은 정보들은 json - text 형식으로 작성된다. 이건 사람이 알아볼수 있는 구조가 아니기 때문에 django에서 파이썬 언어로 알아볼수 있도록 따로 지정해 준다.
from django.http import JsonResponse
data = json.loads(request.body)
또한 통신을 통한 정보는
key 와 value
의 형태로 이뤄져 있다. 때문에 request로 받은 정보는 value를 저장하는 것이다.! (??) -> 확신은..없음...
def post(self, request):
data = json.loads(request.body)
menu = Menu.objects.create(name=data['menu']
category = Categories.objects.create(
name=data['category'],
menu = menu // 함수 생성과 동시에 변수로 지정할 수 있다.
product = Product.objects.create(
name=data['product']['name']
category = category)
return JsonResponse({'MESSAGE' : 'SUCCESS'}, status=201)
위에 get 메소드
를 작성하면서 설정한것으로 간다.