C.R.U.D #2 Exercise (주인과 강아지 프로젝트)

Jayson Hwang·2022년 5월 10일
0

Django Basics

목록 보기
5/14
post-thumbnail

목표:

  1. URLconf, View를 활용하여 리스트를 표출하는 엔드포인트 작성
  2. 엔드포인트의 결과로 return할 JSON data 생성
  3. httpie를 이용하여 GET/POST 요청보내기

1.. Httpie 설치

  • python으로 개발된 http client 유틸리티
  • http통신으로 서버와 연결하여 작업이 가능하게 해주는 도구

$ pip install httpie

사용예시

$ http -v POST 127.0.0.1:8000/owners name='홍길동' email='abc123@naver.com' age=25
$ http -v GET 127.0.0.1:8000/owners


2.. Models.py 작성

models.py 에 Model Class 작성을 통해서 Database의 테이블과 Mapping
owners/models.py

from django.db import models

#Owner Class
class Owner(models.Model):
    name = models.CharField(max_length=45)
    email = models.CharField(max_length=300)
    age = models.IntegerField()

    class Meta:
        db_table = 'owners'

#Dog Class
class Dog(models.Model):
    name = models.CharField(max_length=45)
    age = models.IntegerField
    owner = models.ForeignKey("Owner", on_delete=models.CASCADE)

    class Meta:
        db_table = 'dogs'

models.py 작성한 내용 DB에 적용

# 1. makemigrations : migration 파일 생성(설계도 생성)
$ python manage.py makemigrations

# 2. migrate : 생성한 migration파일을 database에 적용
$ python manage.py migrate

3.. Views.py 작성

3-1.. OwnersView POST/GET method

  • Outline 작성
def post(self, request):
		"""
        목적: Client가 보내주는 owner정보(name, age, email) 등록 요청에 맞게 owner테이블 in database 에 저장

        Input: 
             {
         'name'  = '홍길동'
         'age'   = 20
         'email' = asd@gmail.com
             }

        Logic: 
             1. owner 모델을 사용해서 owner 테이블에 데이터 입력
             2. Owner.objects.create(...)

        Output: 
             {
                 "message": "SUCCESS"
             }, status = 201
        """
        return HttpResponse(201)
        
        

def get(self, request):
        """
        목적: owners의 정보를 client 요청하는 바와 맞게 database에서 호출하고, 가공해서 응답(반환)

        Logic: 
         1. 응답해야할 방식에 맞춰주기 위해서 빈 리스트 생성 / results = []

         2. 모든 owner의 정보 추출 / owners = Owner.Objects.all()

         3. for loop으로 강아지 리스트(name , age 포함되도록)가 함께 응답될 수 있도록 짜야함


        Output: 
             {
         "results" = result
         },         status = 200

        """
        return HttpResponse(200)
  • 실제 내가 작성한 코드 :::
import json

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

from owners.models import Owner, Dog


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

        Owner.objects.create(
            name  = data['name'],
            age   = data['age'],
            email = data['email']
        )
        return JsonResponse({"message" : "SUCCESS"}, status = 201)
  	
    def get(self, request): 
        for owner in owners: 
            dogs = list(Dog.objects.filter(owner=owner.id).values('name', 'age'))
            results.append(
                {
                    'name' : owner.name,
                    'age'  : owner.age,
                    'email': owner.email,
                    'dogs' : dogs,
                }
            )


        return JsonResponse({'results' : results}, status = 200)
  • Refactoring ver. 1 (List Comprehension 사용하여 list 줄이기)
    문제::: dogs = list(Dog.objects.filter(owner=owner.id).values('name', 'age'))
  results = []
  owners  = Owner.objects.
  for owner in owners: 
      results.append(
          {
              'name' : owner.name,
              'age'  : owner.age,
              'email': owner.email,
              'dogs' : [{
                  'name': dog.name,
                  'age' : dog.age,
              } for dog in owner.dog_set.all()]
          }
      )
  • Refactoring ver. 2 ( results = [] ▶︎ List Comprehension)
  results = [
      {
              'name' : owner.name,
              'age'  : owner.age,
              'email': owner.email,
              'dogs' : [{
                  'name': dog.name,
                  'age' : dog.age,
              } for dog in owner.dog_set.all()]             
      } for owner in Owner.objects.all()
  ]

:::: POINT

  • OneToMany에서 역참조(_set)의 사용법 숙지
  • 새로운 리스트를 다시 생성해야할 경우, List Comprehension을 통해서 코드를 줄일 수 있음

:::::: 추가 자료(추가적으로 계속 활용해야함)

  • shell을 연습장처럼 이용해서 계속해서 코드를 확인해나가면서 작업해야함
  • pip install ipython ▻ shell을 보기 편하게 만들어줌
  • pip install django-extensions ▻ shell_plus를 사용 가능하게 해줌(기타 Django Extensions)
  • setting.py 의 INSTALLED_APPSdjango_extensions를 추가해야함
  • python manage.py shell_plus ▻ shell_plus를 사용해서 더 좋은 shell을 사용 가능!!!!!!


3-2.. DogsView POST/GET method

  • Outline 작성
def post(self, request):
      """
      목적: Client가 보내주는 dog정보(name, age, owner_id) 등록 요청에 맞게 dog테이블 in database 에 저장

      Input: 
          {
      'name'  = '라온'
      'age'   = 1
      'owner' = '홍길동'
          }

      Logic: 
          1. dog 모델을 사용해서 dog 테이블에 데이터 입력
          2. Dog.objects.create()

      Output: 
          {
      "message": "SUCCESS"
          }, status = 201
      """
        return HttpResponse(201)
        
        

def get(self, request):
      """
      목적: dogs의 정보를 client 요청하는 바와 맞게 database에서 호출하고, 가공해서 응답(반환)

      Logic: 
      1. 응답해야할 방식에 맞춰주기 위해서 빈 리스트 생성 / results = []

      2. 모든 dog의 정보 추출 / dogs = Dog.Objects.all()


      Output: 
          {
      "results" = result
      },         status = 200

      """
        return HttpResponse(200)
  • 실제 내가 작성한 코드 :::
    (List Comprehension으로 줄여줄 수 있음)
class DogsView(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_id = owner.id
        )
        return JsonResponse({"message" : "SUCCESS"}, status = 201)
        
        
        
    def get(self, request): 
        results = []
        dogs    = Dog.objects.all()
        
        for dog in dogs: 
            results.append(
                {
                    'name' : dog.name,
                    'age'  : dog.age,
                    'owner': dog.owner.name
                }
            )
        return JsonResponse({"results" : results}, status=200)

4.. URLconf 설정

4-1.. 최상위(project) urls.py 파일에 app 경로 추가

  • setting.py 파일이 있는 폴더 안에 urls.py를 찾으면 편하다.

from django.urls import path, include

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

4-2.. App 안에 urls.py 생성

  • $ touch urls.py 명령어로 생성

4-3.. App의 urls.py 파일에 view class 경로 추가

from django.urls import path
from owners.views import OwnersView, DogsView

urlpatterns = [
    path('owners', OwnersView.as_view()),
    path('dogs', DogsView.as_view())
]
  • 제대로 mapping 안해주면 400에러 자꾸 뜸


5.. 서버 실행 후, POST / GET 작동 확인

  • $ python manage.py runserver 0:8000 로 서버 실행(오류없는지 확인)
  • httpie(client)로 django server에 요청 보내기
'''
Owners
http -v POST http://localhost:8000/owners name='홍길동' email='qwert@gmail.com' age=21
http -v GET http://localhost:8000/owners

Dogs
http -v POST http://localhost:8000/dogs name='라온' age=1 owner='홍길동'
http -v GET http://localhost:8000/dogs
'''

6.. 관련 Images

Httpie 호출 결과


Database table

class OwnersView, DogsView


profile
"Your goals, Minus your doubts, Equal your reality"

0개의 댓글