지난 C.R.U.D 1에서는 Django Application에서 MTV pattern의 Model을 작성하고 DB와 통신하는 방법을 알아봤습니다.
이번에는 HTTP통신을 통해 Client(Httpie, Chrome, Postman, etc)를 사용해서 Server에 요청을 보내고 Django Application을 통해 요청을 분석(URLconf)하고 요청을 처리하고 위한 Logic(View)을 실행시켜 DB와 통신(Model)하여 데이터 작업을 수행하고 요청에 맞는 응답을 보낼 수 있는 Backend API을 구현한다. 출저
HTTP(Hypertext Transfer Protocol) 은 Web server와 Web client사이에서 data를 주고받기 위해 사용하는 통신 방식이다. 특징은 stateless이다. 이 말은 client와 server의 연결이 지속되지 않고 한번의 요청과 응답으로 종료가 된다.
HTTP 처리 방식
HTTP Method를 통해 Client가 원하는 처리 방식을 Server에 알려주며 data 조작의 기본이 되는 C.R.U.D(Create, Read, Update, Delete)와 Mapping되는 처리를 한다.
메소드명 | 의미 | C.R.U.D와 맵핑 |
---|---|---|
GET | 데이터(리소스) 취득 요청 | READ |
POST | 데이터(리소스) 생산 요청 | CREATE |
PUT | 데이터(리소스) 변경 수정 요청 | UPDATE |
DELETE | 데이터(리소스) 삭제 요청 | DELETE |
예시로 만들 프로젝트는 주인과 주인이 소유한 강아지를 DB에 저장하고 저장된 리스트를 불러 올수 있어야 한다.
feature/owner
브랜치에서 owners
app을 생성 후 필수 과제 진행위에 강아지와 주인의 테이블을 참조해서 application directory 내에 있는 models.py를 작성한다.
from django.db import models
class Owner(models.Model):
name = models.CharField(max_length=45)
email = models.CharField(max_length=300)
age = models.PositiveBigIntegerField()
# age cannot be negative number
class Meta:
db_table = 'owners'
class Dog(models.Model):
name = models.CharField(max_length=45)
age = models.PositiveIntegerField()
owner = models.ForeignKey('Owner', on_delete=models.CASCADE)
# owner = models.ForeignKey(Owner, on_delete=models.CASCADE, related_name='dogs')
# Dog need owner in order to be in DB, use owner FK
class Meta:
db_table = 'dogs'
models.py를 작성을 완료를 했으면 migration과 migrate를 통해 DB내에 모델을 생성해주어야 한다. 그래야 후에 데이터를 집어 넣을 수 있는 공간이 만들어 지기 때문에 잊지말고 migrate까지 완료해주자.☝
만든 Application directory 내에 있는 views.py를 통해서 POST method와 GET method를 만든다. POST method에는 신규 주인 등록과 강아지 등록(주인정보 필요) 2가지 기능을 각 서로 다른 클래스로 구현한다. GET method에는 주인 리스트(이름, 이메일, 나이), 강아지(이름, 나이, 주인 이름), 그리고 주인 리스트(키우는 강아지 리스트(나이, 이름))를 포함한 3가지 기능을 각 클래스로 구현한다.
Class 안의 method를 구성하는 것이므로 첫번째 parameter에는 self가 들어가야한다. Views.py 에서 request를 지정하는 이유는 현재 Client와 통신을 해야하는 상황으로 Client의 request은 Json 형식으로 request(요청)이 들어오게 된다. 이때 Django는 접근하기 쉽도록 Json -> dictionary
형태의 자료구조로 변환하여 주는데 이 정보를 request 라는 객체에 저장해주기 때문에 두번째 parameter로 지정을 해준다.
먼저 주인의 post와 get method를 view파일에 작성을 합니다.
class OwnerView(View):
# 신규 주인을 등록
def post(self, request):
# request에 front가 준 모든 정보를 포함한다
# front가 준 정보는 json이라 dictionary로 변환해준다
data = json.loads(request.body)
owner = Owner.objects.create(
name = data['name'],
email = data['email'],
age = data['age']
)
return JsonResponse({"message" : "owner created"}, status=201)
def get(self, request):
result = []
owners = Owner.objects.all()
for owner in owners:
owner_information = {
'name' : owner.name,
'email' : owner.email,
'age' : owner.age
}
result.append(owner_information)
return JsonResponse({'result' : result}, status=200)
# 역참조는 여러 데이터들을 가지고 오기 때문에 all이나 filter같은 function이 필요하다.
def get(self, request):
result = []
owners = Owner.objects.all()
for owner in owners:
dogs = owner.dog_set.all()
dog_list = []
for dog in dogs:
dog_information = {
'name' = dog.name,
'age' = dog.age
}
dog_list.append(dog_information)
owner_information = {
'name' : owner.name,
'email' : owner.email,
'age' : owner.age,
'dogs' : dog_list
}
result.append(owner_information)
return JsonResponse({'result' : result}, status=200)
그 다음으로 강아지의 post와 get method를 view파일에 작성을 합니다.
class DogView(View):
def post(self, request):
data = json.loads(request.body)
owner = Owner.objects.get(name=data['owner'])
Dog.objects.create(
name = data['name'],
age = data['age'],
owner = owner
)
return JsonResponse({'message' : "SUCCESS"}, status=201)
def get(self, request):
result = []
dogs = Dog.objects.all()
for dog in dogs:
dog_information = {
'name' : dog.name,
'age' : dog.age,
'owner' : dog.owner.name
}
result.append(dog_information)
return JsonResponse({'result' : result}, status=200)
먼저 Server에 HTTP request를 할 수 있는 Httpie를 설치한다.
Ubuntu
$ sudo apt intstall httpie
models.py를 기반으로 views.py에서 methods 별로 전부 작성을 하고 나면 이제는 application을 서버와 이어주기 위해서 url을 모두 연결시켜 줘야 한다. 가장 먼저 request 요청이 들어오는 (project 이름)/urls.py와 (app 이름)/urls.py(따로 파일을 생성해줘야 한다)에 경로를 설정해 주어야 한다.
HTTP 통신에서 request가 제일 먼저 URL로 들어오기에 owners/
부분에 따라 request요청이 달라진다. http -v POST 127.0.0.1:8000/owners/(app url경로)
를 사용해서 통신이 가능하다.
from django.urls import path, include
urlpatterns = [
path('owners', include('owners.urls')),
]
아래는 application/urls.py의 경로 설정이다.
from django.urls import path
from owners.views import OwnersView, DogsView
urlpatterns = [
path('/owner', OwnersView.as_view()),
path('/dog', DogsView.as_view())
]
후에 httpie를 이용해서 성공적으로 불러온다면
{
"results": [
{
"name": "(강아지 이름)",
"age": "(강아지 나이)",
"owner": "(강아지 주인 이름)"
},
{
"name": "(강아지 이름)",
"age": "(강아지 나이)",
"owner": "(강아지 주인 이름)"
},
.
.
.
]
}
위와 같은 결과가 나올것이다.