TIL #13 CRUD과제

tycode·2021년 6월 21일
0

TIL

목록 보기
15/30

주인과 강아지

POST

각 기능을 서로 다른 클래스로 구현해주세요.

  1. 신규 주인 등록
  2. 강아지 등록 (주인정보 필요)

위 기능을 구현 후 직접 httpie 를 활용하여 주인 2명의 정보와 각 주인 당 2~3마리의 강아지 정보를 데이터베이스에 저장해주세요.

GET

각 기능을 서로 다른 클래스로 구현해주세요.

  1. 주인 리스트
    • 이름, 이메일, 나이 포함
  2. 강아지 리스트
    • 이름, 나이, 주인 이름 포함
  3. 주인 리스트 (1번 코드에 추가)
    • 이름, 나이 포함, 키우는 강아지 리스트 (이름, 나이 포함)

models.py

from django.db import models

class Owner(models.Model):
        name    = models.CharField(max_length=45, null=True, blank=True)
        email   = models.CharField(max_length=45, null=True, blank=True)
        age     = models.PositiveSmallIntegerField(null=True, blank=True)

        class Meta:
                db_table = 'owners'

class Dog(models.Model):
        owner   = models.ForeignKey('Owner', on_delete=models.CASCADE)
        name    = models.CharField(max_length=45, null=True, blank=True)
        age     = models.PositiveSmallIntegerField(null=True, blank=True)

        class Meta:
                db_table = 'dogs'
  • 먼저 모델링한 것을 데이터베이스에 넣어주었다.

urls.py

(최상위 URLconfig)
from django.urls import path, include


urlpatterns = [
        path('owners', include('owners.urls'))
]
  • owners라는 app을 생성했다.
  • include를 포함하여 서버에서 요청할시 owners의 urls.py로 path 지정했다.
(앱) owners.urls.py
from django.urls import path
from .views import OwnerView, DogView

urlpatterns = [
        path('/owner', OwnerView.as_view()),
        path('/dog', DogView.as_view())
]
  • 최상위 urls는 앱의 urls로 인도함.
  • urlpatterns에 처음엔 path('', ) 만 넣고 view.py 작성후 path값을 다시 urls.py에 넣어주었다.
  • as_view : http요청이 해당 클래스로 요청이 들어올 때, get, post, update, delete인지 등에 맞게 알아서 처리해줌.

views.py

공통부분
import json
from django.views import View
from django.http import JsonResponse
from .models import Owner, Dog
  • GET요청일 때 JsonResponse
  • .(dot) 현재 있는 폴더에서 Owner, Dog 불러옴

POST

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

        Owner.objects.create(
            name  = data['name'],
            email = data['email'],
            age   = data['age']
        )

        return JsonResponse({'message':'SUCCESS'}, status=201)
  • request: http의 요청에 대한 모든 정보를 담고 있는 객체. body, status, query string 등을 가져옴
Dog POST
class DogView(View):
    def post(self, request):
        data  = json.loads(request.body)

            owner = Owner.objects.get(email=data['owner']) # owner
            Dog.objects.create(
                name  = data['name'],
                age   = data['age'],
                owner = owner
            )
            return JsonResponse({'message':'SUCCESS'}, status=201)
  • owner의 email을 PrimaryKey로 했기 때문에 email을 불러와야 강아지 데이터를 넣을 수 있다.
  • Owner.objects.get(email....)을 owner라는 변수에 넣어서 create함수 아래에 owner=owner라고 두었다.

GET

GET은 쿼리셋으로 넘겨줘야 되기 때문에, Json이 이해할 수 있도록 dictionary형식으로 넘겨야한다.

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

            result = []
            for owner in owners:
                dogs = owner.dog_set.all() #Owner로 Dog를 참조
                dogs_list = []
                for dog in dogs:
                    dog_info = {
                        'name' : dog.name,
                        'age'  : dog.age
                    }
                    dogs_list.append(dog_info)

                owner_info = {
                    'email' : owner.email,
                    'name'  : owner.name,
                    'age'   : owner.age,
                    'dogs'  : dogs_list
                }

                result.append(owner_info)

            return JsonResponse({'result': result}, status=200)
  • #Owner클래스가 모델 클래스 Dog를 (소문자로) _set로 역참조 했다.
  • 주인을 owners라는 변수에 담아서,
  • (owners = ) Owner.objects.all()에서 dogs 테이블을 역참조 했다.
  • 각 owner가 소유하고 있는 dog들을 dog_info에 딕셔너리 형태로 담고 그걸 dogs_list에 리스트 형태로 넣었다.
  • 그리고 owner_info에 dogs_list를 딕셔너리 형태로 포함시켜 result라는 리스트에 담았다.
Dog GET

    def get(self, request):
        dogs = Dog.objects.all()

            result = []
            for dog in dogs:
                dog_info = {
                    'owner' : dog.owner.name, #foreignkey를 사용했으니, dog의 owner name을 불러옴
                    'name'  : dog.name,
                    'age'   : dog.age,
                }

                result.append(dog_info)
            return JsonResponse({'result': result}, status=200)
  • 강아지 변수들을 dogs에 담아 for문을 돌려서 테이블에서 dog's owner, name, age를 dog_info 딕셔너리에 담았다.

List Comprehension

my_list = [1, 2, 3, 4, 5]

b = [num for num in my_list]
print(b)

#출력
[1, 2, 3, 4, 5]
  • my_list의 num이란 변수들마다 b안에 넣겠다라는 뜻.
my_list2 [{'a': 1, 'b': 2}, {'a,': 3, 'b' : 4}]

b = [num['a'] for num in my_list2]
print(b)

# 출력
[1, 3]
  • num은 딕셔너리 형식이다. 그런데 num 딕셔너리 안에 있는 a만 불러오고 싶다면, num['a']를 한다.
GET OWNER - Version2
class OwnerView(View):
    def get(self, request):
        owners = Owner.objects.all()

            result = []
            for owner in owners:
                dogs = owner.dog_set.all()

                dogs_list = [{
                'name': dog.name,
                'age' : dog.age
                } for dog in dogs]

                owner_info = {
                    'email' : owner.email,
                    'name'  : owner.name,
                    'age'   : owner.age,
                    'dogs'  : dogs_list
                }

                result.append(owner_info)

            return JsonResponse({'result': result}, status=200)
  • dogs_list를 list comprehension을 사용함.
    ✅ list comprehension을 쓰면 깔끔하고 더 좋게 보인다 하지만, if문 하나까지는 쓰고 그 이상은 불편하더라도 for문을 겹쳐서 쓰는게 좋다.

0개의 댓글