Django CRUD (2)

최창환·2022년 3월 20일
0
post-thumbnail

CRUD (2) 에서는 HTTP 통신을 통해 Client에서 Server에 요청을 보내고 Django Application 을 통해 요청을 분석(URLconf) 하고 요청을 처리하기 위한 로직(View) 을 실행시켜 데이터베이스와 통신(Model) 하여 데이터 작업을 수행하고 요청에 맞는 응답을 보낼 수 있는 Backend API를 구현한다.

Model 작성

다음의 ERD를 참고하여 적절한 Models.py를 작성하고 Database와 연동시켰다.

from django.db import models

# Create your models here.
class Owner(models.Model):
    name = models.CharField(max_length=20)
    email = models.CharField(max_length=45)
    age = models.IntegerField(default=0)

    class Meta:
        db_table = 'owners'

class Dog(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField(default=0)
    owner = models.ForeignKey('Owner', on_delete=models.CASCADE)

    class Meta:
        db_table = 'dogs' 

Models.py 작성 후 Migration파일을 생성하고 적용하여 Mysql database에 제대로 연동된것을 확인하였다.

View 작성

Model 작성이 완료되었으니 이제 요청을 처리하기 위한 로직을 만들기 위해 View를 작성하자

POST

import json

# from django.shortcuts import render
from django.http    import JsonResponse
from django.views   import View

from owners.models  import Owner, Dog

# Create your views here.
class OwnerView(View):   
    def post(self, request):
        try:
            data  = json.loads(request.body)
            owner = Owner.objects.create(
                name  = data['name'],
                email = data['email'],
                age   = data['age']
            )
            return JsonResponse({'message':'created'}, status=201)

        except KeyError:
            return JsonResponse({'error':'KeyError'}, status=400)

class DogView(View):
    def post(self, request):
        data = json.loads(request.body)
        owner = Owner.objects.get(name=data['owner'])
        dog = Dog.objects.create(
            name = data['name'],
            age = data['age'],
            owner = owner
        )

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

post 메소드로 주인의 정보3가지와 강아지의 정보3가지를 각각 요청하는 기능을 구현하였다.

GET

class OwnerView(View): 
	def get(self, request):
        owners = Owner.objects.all()

        results = [{
            "name"  : owner.name,
            "email" : owner.email,
            "age"   : owner.age,
            "dogs"  : [{
                "name" : dog.name,
                "age"  : dog.age
            } for dog in owner.dog_set.all()]
        } for owner in owners]


        # results = []

        # for owner in owners:
        #     # dogs = Dog.objects.filter(owner=owner)
        #     dogs = owner.dog_set.all()
        #     dog_list = []

        #     for dog in dogs:
        #         dog_list.append(
        #             {
        #                 "name" : dog.name,
        #                 "age" : dog.age
        #             }
        #         )
        #     results.append(
        #         {
        #             "name" : owner.name,
        #             "email" : owner.email,
        #             "age" : owner.age,
        #             "dog" : dog_list
        #         }
        #     )

        return JsonResponse({'results':results}, status=200)
        
class DogView(View):
	def get(self, request):
        dogs = Dog.objects.all()
        results = []

        for dog in dogs:
            results.append(
                {
                    "name" : dog.name,
                    "age" : dog.age,
                    "owner" : dog.owner.name
                }
            )

        return JsonResponse({'reults':results}, status=200)

GET 메소드를 통하여
주인 리스트(이름, 이메일, 나이, 키우는 강아지 리스트)
강아지 리스트(이름, 나이, 주인 이름 포함)
의 정보를 얻어오는 기능을 구현하였다.

문제는 1:N인 관계인 owner와 dog에서 1쪽인 owner에서 dog을 참조할 때인데 이렇게 부모테이블에서 역으로 참조할 때는 역참조를 사용하면 된다.

객체.모델이름_set의 형식으로 사용하는데 여기서는 owner.dog_set을 사용하여 owner테이블에서 dog테이블을 참조하였다.

그리고 이중 for문이 사용되어 코드가 길어지게 되었는데 멘토님이 list comprehension을 사용하여 코드의 길이를 줄이는것을 따라해 보았는데 확실히 코드의 길이가 짧아지면서 보기에도 간결해보여서 앞으로는 되도록 list comprehension을 활용하는 방식으로 코드를 짜야겠다.


URLconf

View를 작성하였으니 이제 클라이언트의 요청을 받아 적절한 view를 맵핑해주는 urls.py를 작성하자

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

from owners.views import OwnerView, DogView

urlpatterns = [
    path('/owners', OwnerView.as_view()),
    path('/dogs', DogView.as_view()),
]

# wecrud/urls.py
from django.urls import path, include

urlpatterns = [
    path('owners', include('owners.urls')),
]

url맵핑도 완료하였으니 이제 서버를 실행하고 httpie로 요청을 보내보자.

http -v POST 127.0.0.1:8090/owners/owners name='John' email='j123@gmail.com' age=28

http -v POST 127.0.0.1:8090/owners/dogs name='해피' owner='John' age=10

http -v GET 127.0.0.1:8090/owners/owners
http -v GET 127.0.0.1:8090/owners/dogs

profile
포기하지 않는 개발자

0개의 댓글