Django - CRUD2

do yeon kim·2022년 7월 5일
0

CRUD

이전 수업

앞서 CRUD1 수업에서 데이터베이스에 필요한 데이터모델링을 했다.

데이터모델링을 통해 데이터베이스에 들어갈 데이터구조에 대해서 구현했고, Django ORM을 통해서 데이터베이스에 데이터를 넣어 주었다.

Menu.objects.create(name = "음료")


menu1 = Menu.objects.create(name = "빵")
Category.objects.create(name="식빵", Menu = menu1)

이번에는 데이터베이스에 들어간 데이터를 활용해서 사용자의 요청(GET, POST)에 맞게 view.py에서는 데이터를 이용한 로직을 urls.py에는 URLConfig로 알맞은 주소로 이동시켜보자!!!







POST 방식 코드분석

<전체코드>


<import코드>

import구문의 경우 통상적으로 다음과 같은 순서로 import순서가 정해져 있다.

  • 파이썬 내장모듈
  • pip로 설치된 외부모듈
  • 사용자 설정 모듈

import json

  • HTTP통신의 BODY에서 주고 받는 데이터 타입은 주로 JSON타입이다.
    파이썬내에서는 JSON타입을 바로 사용할 수 없으므로, 사용가능한 형태로 변경을 위해서 import해 주었다.

from django.http import JsonResponse
from django.views import View

  • HTTP통신에서 사용자의 요청에 응답하기 위해서도 JSON타입이 필요하다.
    그러기 위해서 파이썬내에서 사용을 위해 사용자 요청시 들어온 JSON타입을 파이썬내에서 사용하기 위해 데이터타입을 변경한 것을 다시 JSON타입으로 변경해주어야 한다.

  • class정의시 View를 상속하기 위해서 import해준것이다.


from products.models import Menu, Category, Product

  • 앞서 데이터모델링시 사용한 데이터구조를 가지고 와서 사용한다.


<class코드>

실제 로직에 해당하는 부분을 구현한 코드이다.
클래스 이름은 대문자로 시작하며, 어떤데이터를 다룰 것인지를 알 수 있는 네이밍을 한다. 이름의 마지막은 View로(상속모델에 있는 클래스와 구분을 위해) 끝내는 것이 통상적이다.

클래스 내부의 함수 하나하나가 API가 된다.
함수명은 HTTP통신의 METHOD명과(POST, GET, PUT, DELETE 등) 매치시킨다.

함수의 첫번째 파라미터는 클래스이므로 self, 다음은 request를 받는다.
함수가 실행시 클라이언트로부터 request객체가 들어오기 때문에 통상적으로 request라고 적어준다.



<함수코드>

data = json.loads(request.body)
HTTP통신시 대부분의 경우 JSON타입이 온다. 하지만 파이썬에서는 바로 사용하지 못하므로 파이썬에서 사용가능한 타입으로 변경시켜 주어야 한다.
데이터 타입 변경후 보통 딕셔너리형태가 된다.


menu = Menu.objects.create(name = data['name'])

데이터타입이 변경된 data를 이용해서 ORM을 구현한다.


참고
만약 data에 키값이 들어 있지 않다면 키에러가 발생한다.
키에러에 대한 예외처리도 필요하지만, 그보다 중요한 것은 프론트엔드와의 커뮤니케이션이다.

HTTP통신을 통해서 들어오는 데이터는 프론트엔드로 부터 들어오는 것이므로, 프론트엔드와의 커뮤니케이션을 통해 키값에 대해서 정의를 맞추어야 한다.



category = Category.objects.create(name = data[category], menu = menu)

Foreign Key의 경우 객체를 가르키는 위치를 넣어주어야 한다.
그러므로 create의 반환값은 객체이므로 위에서 생성한 객체를 넣어준다.

return JsonResponse({"message": "created"}, status = 201)

return 값은 JSON타입으로 보내야 하므로 JSON타입으로 변경해주는 코드에 해당한다.
값은 딕셔너리 형태로 넣어줌ㄴ다.
첫번째 인자는 딕셔너리 형태, 두번째 인자는 상태코드 를 반환한다.



urls.py

클래스에서 구현한 함수 하나하나가 API라고 했다.
사용자의 요청에 해당하는 API를 호출 하기 위해서는 요청에 해당하는 주소가 필요하다.

요청할 주소는 urls.py 파일 안에 정의한다.

  • main의 urls.py
  • app의 urls.py

main의 url.py에서는 어떤앱에 해당하는지를 결정한다.
appd의 url.py에서는 어떤 API에 해당하는 view를 처리 할 것인지를 결정한다.



main의 urls.py

path(들어온 경로, 보낼곳)
include() 를 이용해서 해당 앱의 url정보로 넘긴다.



붉은 색 url코드의 경우 모두 products.urls로 가게 된다.
여기서는 8000/뒤의 products 부분만 보게 된다.



app의 urls.py

main의 urls.py 를 통해 들어온 url정보를 각 API에 맞게 실행시켜주는 부분이다.

"/"가 빠졌다.

http://127.0.0.1:8000/products/에 해당하는
앞에서 정의한 ProductsView에 해당하는 API가 실행된다.


참고
실제 사용할 뷰를 인포트해주어야 한다. 뷰를 여러개 사용하면 갯수만큼 import해주어야 한다. 앞에 /를 붙힌다.

맨뒤에 /를 붙히지 않는다.
Restful api에서는 뒤에 /를 붙히지 않는다.

Method에 맞지 않으면 Not allowed_method가 발생한다.


as_view()
HTTP통신을 통해 들어온 METHOD와 내가 구현한 함수랑 연결해주는 것이다.



실제 통신해보기

POST방식을 이용해서 통신을 한 것이다. 뒤에 오는 데이터는
HTTP통신의 HEADER 또는 BODY가 된다.
키와 벨류의 형태로 보내며, ,를 사용하지 않는다.
여기서 보낸 키와 벨류로 앞서 구현한 함수 내에서 사용하는 데이터가 된다,

BODY부분에 들어온 데이터는 딕셔너리처럼 보이지만 실제는 JSON이다.

정의되지 않은 메서드보낼 경우 에러가 발생한다.

API명세서가 필요한 이유
어떤 요청이 필요하고 어떤 데이터타입이 와야하는지 적어 놓은 것이다.







POST 방식 코드분석

ORM의 all()은 객체에 대한 모든 정보를 가지고 와서 Query_set을 반환한다.

products = Product.objects.all() 로 변수에 담는다.

Query_set은 리스트와 비슷해서 돌면서 하나씩 요소를 가지고와서 조작한다.

객체형태로 HTTP통신을 할 수 없으므로 JSON타입으로 변경을 위해서
먼저 딕셔너리 형태로 데이터를 저장한다. 각 데이터를 분해하고 뽑아서 새롭게 만들어 낸다.



데이터에 대한 접근

데이터에 접근시 외래키를 이용해서 접근하고 있다.

외래키를 가지고서 접근해야한다.

0개의 댓글