TIL 23 | Django CRUD #2 POST Method

임종성·2021년 7월 19일
1

Django

목록 보기
5/17
post-thumbnail

Django CRUD #1을 통해 MVT Pattern의 Model을 작성하고 Database와 통신하는 법을 배웠다. CRUD #2 에서는 HTTP 통신을 이용해 Client - Server - Database의 data flow를 이해하고, Django Application을 통해 Request를 처리하기 위한 Logic(View)을 실행시켜 Database와 통신(Model)하고 데이터 작업을 수행하여 요청에 맞는 응답을 낼 수 있는 Backend API를 구현한다.

Assignment

Django CRUD #2 에서 주어진 실습 과제는 아래와 같다.

  • 위와 같은 ERD를 참고하여 적절한 Django Model을 작성한 후 Database와 연동한다.
  • 신규 주인을 등록하고 강아지 정보를 등록(주인정보 필요)하는 POST Method의 View Class를 구현한다.
  • 주인 리스트, 강아지 리스트, 주인 리스트(이름,나이,키우는 강아지 포함)를 GET 하는 View Class를 구현한다.

요구하는 기능을 제대로 수행하는 View를 작성하는 것이 이번 과제의 핵심이지만, 그에 앞서 Database에 대응하는 Model부터 작성해야 한다!

Model 구현

먼저 주어진 ERD에 맞도록 models.py에 Owner와 Dog 2개의 Model Class를 작성하여 Database의 Table과 Mapping하였다.

다음으로 작성한 models.py의 코드를 Database에 적용하기 위해 Migration 파일을 생성하고 적용했다.

python3 manage.py makemigrations owners
python3 manage.py migrate owners

이후 MySQL 에서 owners Database에 접속해 Table을 확인하여 제대로 연동된 것을 확인했다.

이제 Model이 제대로 작성되었으니, View를 작성해보자!

View Class 구현

먼저 POST Method의 View Class를 구현했다.

import json

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

from owners.models import Owner, Dog



class OwnerRegister(View):
    def post(self, request):
        data  = json.loads(request.body)

        owner = Owner.objects.create( # 주인의 정보 3가지를 구현
            name  = data['name'],
            email = data['email'],
            age   = data['age']
        )

        return JsonResponse({'Message':'CREATED'}, status=201)


class DogRegister(View):
    def post(self, request):
        data  = json.loads(request.body)

        owner = Owner.objects.get(name=data['owner'])
        dog   = Dog.objects.create( # 강아지의 정보 3가지를 구현
            name  = data['name'],
            age   = data['age'],
            owner = owner			# Foreign Key
        )

        return JsonResponse({'Message':'CREATED'}, status=201)

이렇게 View를 작성한 후, 클라이언트의 요청을 받아 적절한 View를 맵핑해주는 urls.py를 작성했다.

# owners/urls.py
from django.urls import path

from owners.views import OwnerRegister, DogRegister # View의 class들 import

urlpatterns = [
	path('', OwnerRegister.as_view()), #view mapping
    	path('', DogRegister.as_view()),
]
# crud2/urls.py
# from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    	#path('admin/', admin.site.urls),
    	path('owners', include('owners.urls')), # 처음 클라이언트 요청을 받기 위해 
]						# main(crud2) urls.py와 연결

views.py에 적절한 View Class를 만들고 요청을 받는 url들도 맵핑을 완료했다. 이제 python3 manage.py runserver로 서버를 실행하고 httpie로 django server에 요청을 보내보자.

http -v POST 127.0.0.1:8000/owners name='임종성' email='leon111@naver.com' age:=30

위의 코드를 Terminal에 실행하여 주인의 이름, 이메일, 나이를 저장하려 했더니 다음과 같이 성공적으로 Create 되었다는 메시지가 출력되었다!

구현한 기능이 제대로 작동하는 걸 확인했으니 과제가 요구하는 대로 내가 좋아하는 반려견 유투버 두명의 정보를 입력해주었고, MySQL에서 Table로 출력해봤다.(나이는 불명확)

이제 각 유투버가 데리고 있는 반려견들의 정보를 입력할 차례다. 그런데..

여러 View Class의 Url Mapping

주인의 정보를 입력한대로 강아지의 정보도 입력하면 되겠지? 라는 마음으로 다음과 같이 코드를 적었더니 에러가 발생했다.

http -v POST 127.0.0.1:8000/owners name='곰이' owner='쏭이님' age:=7

에러 내용을 보니 email KeyError가 발생했다. 그런데 email은 View의 DogRegister Class가 아니라 OwnerRegister Class에 존재하는 변수다. 그렇다는 것은 내가 입력한 httpie 코드가 DogResiter가 아니라 OwnerRegieter를 불러냈다는 말이다.

곰곰히 생각해보니 httpie 코드가 View의 어떤 Class를 불러오는건지 구별을 못하는 것 같았다. 아무리 생각해도 url mapping이 필요하다고 생각하고 owners/urls.py의 코드를 다음과 같이 변경했다.

# owners/urls.py
from django.urls import path

from owners.views import OwnerRegister, DogRegister 

urlpatterns = [
	path('owners', OwnerRegister.as_view()), # ''을 'owners`로
    	path('dogs', DogRegister.as_view()),     # ''을 'dogs'로
]

각 클래스별로 path에 공백이 아니라 ownersdogs를 넣으면

http -v POST 127.0.0.1:8000/owners/dogs name='곰이' owner='쏭이님' age:=7

처럼 owners/dogsowners/owners로 각 클래스로 mapping 할 수 있다고 생각하고 실행했더니 Not Found Error가 발생했다..

왜 안되는걸까.. 라고 생각하고 crud2/urls.py까지 뒤져보니 문제를 알 수 있었다.

# crud2/urls.py
# from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    	#path('admin/', admin.site.urls),
    	path('owners', include('owners.urls')), 
]						

admin path부분을 주석처리한게 정말 다행인지.. 'admin/' 처럼 뒤에 '/'가 붙어있어야 인식할 수 있는 것 같았다! 이걸 보고 바로 path('owners/',~~로 수정했고, 바로 성공한 걸 확인했다!

이제 그대로 httpie 코드를 이용해 각 주인별 3마리의 강아지를 등록했다.


각 기능을 다른 클래스로 구현하고 에러에 대해 끙끙대다보니 이렇게 urls mapping에 대해 스스로 해결하고 이해할 수 있어서 조금 성취감을 느꼈다.. 아무튼 이렇게 구현한 View를 실행하여 요청에 맞는 응답을 해준 것을 확인할 수 있었다! 다음은 Get Method의 View Class를 구현할 차례다.

profile
어디를 가든 마음을 다해 가자

0개의 댓글