Django | C.R.U.D 1 과제 - Westarbucks Modeling

celeste·2022년 4월 10일
0

Django Basics

목록 보기
4/7
post-thumbnail

IPython 설치

기존 파이썬 shell을 사용해도 되지만 ipython이라는 패키지를 사용해 조금더 GUI 환경이 가미된 shell로 작업해보자.

pip install ipython

이후 ipython 명령어 입력하면 ipython shell 이 실행된다.

하지만 우리는 django 프로젝트 프레임워크를 사용해 진행중이기 때문에 장고 기능을 쓸 수 있도록 ipython에 진입해야한다.

python manage.py shell

다음 명령어를 실행하면 자동으로 ipython이 열린다.

App 만들기

Products라는 앱에서 만들기

Model 작성하기

1. models.py 작성

Database의 표가 되는 코드:

from django.db import models

class Category(models.Model):
    menu = models.ForeignKey('Menu', on_delete=models.CASCADE)
    name = models.CharField(max_length=45)

    class Meta:
        db_table = 'categories'

class Menu(models.Model):
    name = models.CharField(max_length=45)

    class Meta:
        db_table = 'menu'

class Drink(models.Model):
    category = models.ForeignKey('Category', on_delete=models.CASCADE)
    korean_name = models.CharField(max_length=45)
    english_name = models.CharField(max_length=45)
    description = models.TextField()

    class Meta:
        db_table = 'drinks'

class Allergy_Drink(models.Model):
    allergy = models.ForeignKey('Allergy', on_delete=models.CASCADE)
    drink = models.ForeignKey('Drink', on_delete=models.CASCADE)

    class Meta:
        db_table = 'allergy_drink'

class Allergy(models.Model):
    name = models.CharField(max_length=45)
    drink_set = models.ManyToManyField(Drink, through=Allergy_Drink)

    class Meta:
        db_table = 'allergy'

class Nutritions(models.Model):
    one_serving_kca = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    sodium_mg = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    saturated_fat_g = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    sugars_g = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    protein_g = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    caffeine_mg = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    drink = models.ForeignKey('Drink', on_delete=models.CASCADE, null=True)
    size = models.ForeignKey('Size', on_delete=models.CASCADE, null=True)

    class Meta:
        db_table = 'nutritions'

class Image(models.Model):
    image_url = models.CharField(max_length=2000)
    drink = models.ForeignKey('Drink', on_delete=models.CASCADE)

    class Meta:
        db_table = 'images'

class Size(models.Model):
    name = models.CharField(max_length=45)
    size_ml = models.CharField(max_length=45, null=True)
    size_fluid_ounce = models.CharField(max_length=45, null=True)

    class Meta:
        db_table = 'sizes'=

??drink_set = models.ManyToManyField(Drink, through=Allergy_Drink)

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

  • app (products) 폴더 들어가면 migrations라는 파일이 있다. 들어가면 __init__.py 파일밖에 없다.

  • 다시 ..manage.py가 있는 최상위 폴더로 나간 후, 아래 코드를 실행하자.

makemigrations: models.py에 작성한 python code를 database에 적용하기 위한 migration 파일(설계도)를 만드는 과정

python manage.py makemigrations app이름

app이름 치면 해당 앱에서만 적용하고, 없으면 모든 앱에서 적용되는데, 웬만하면 적용하는게 좋다.
migrate: makemigration으로 생성한 migration 파일(설계도)을 database에 적용

python manage.py migrate

3. Mysql Server(Database)에 잘 적용되었는지 확인

Cmd + Shift + D
로 split view new terminal 열어서

#database 접속
mysql -u root -p

#database list 보기
mysql> show databases;

#database 선택
mysql> use westarbucks;

#만든 tables 보기
mysql> show tables;

자꾸 empty set이라고 나와서 product 뒤에 붙여줬더니 (python manage.py migrate products) 되었다!


QuerySet 작성하기

지금까지 models.py에 작성한 것은 테이블의 column및 기본 속성!
이제 테이블 내 데이터들을 채워 줄 차례이다

Django shell을 통해서 대화형식으로 DB와 소통이 가능한데,
위에서 ipython을 설치했기 때문에 shell을 부르면 자동으로 ipython이 열린다.

python manage.py shell

👆🏻 코드를 입력하면 DB와 직접 대화할 수 있는 shell창이 열린다.
manage.py는 Django에게 최상위 폴더로 인식되기 때문에, 내가 사용하고자 하는 폴더 내 파일의 클래스(테이블)를 import 해주어야 한다.

from products.models import Menu, Category

#귀찮아서 다 import
from products.models import *

1. Create

참조를 이용하지 않은 INSERT

참조를 이용하지 않는다는 것은, 외부 테이블의 pk값을 가져오는 게 없이
값을 저장한다는 의미이다.

해당 테이블 : Menu, Allergy

우선 models.py에서 데이터베이스에 접근하기 때문에,
해당 파일을 import 해준다.

그리고 우선 가장 상위 카테고리인 메뉴만 만들 예정이다.

from products.models import Menu, Allergy

#Menu, allergy 테이블 조회
Menu.objects.all()
Allergy.objects.all()

##빈 쿼리 셋이 출력된다
QuerySet[]

#Menu 데이터 입력
#스타벅스의 홈페이지가면 '음료', '보도자료', '푸드', '상품', '카드'가 있다.
Menu.objects.create(name='음료')
Menu.objects.create(name='보도자료')
Menu.objects.create(name='푸드'
Menu.objects.create(name='상품')
Menu.objects.create(name='카드')

#Menu 테이블 조회 use SQL
select * from menus;

#Menu 테이블 조회 use ORM
Menu.objects.all()

##쿼리셋이 출력된다(괄호안의 숫자는 id값이다)
<QuerySet [<Menu: Menu object (1)>, <Menu: Menu object (2)>, <Menu: Menu object (3)>, <Menu: Menu object (4)>, <Menu: Menu object (5)>]>

Allergy도 똑같이 해준다

Allergy.objects.create(name='대두')
Allergy.objects.create(name='우유')
Allergy.objects.create(name='난류')
Allergy.objects.create(name='밀')
Allergy.objects.create(name='아황산류')
Allergy.objects.create(name='토마토')

Size

Size.objects.create(name = 'Tall', size_ml = 355, size_fluid_ounce = 12)
Size.objects.create(name = 'Grande', size_ml = 470, size_fluid_ounce = 16)
Size.objects.create(name = 'Venti', size_ml = 709, size_fluid_ounce = 20)

참조를 이용하는 INSERT

1가지 참조하는 객체 생성

mysql>desc categories를 보면,

카테고리는 메뉴의 PK값을 참고하고 있다는 것을 알 수 있다. (FK가지고 있음)
스타벅스 페이지에서, 메뉴와 카테고리를 보면, 메뉴에서 음료를 눌러야 음료 카테고리가 나온다.

그리고 음료와 카테고리를 OneToMany로 설정했는데,
메뉴를 '음료'로 선택하면 선택할 수 있는 카테고리는 10개

메뉴=음료(1):카테고리=콜드브루커피(many)

그러면 카테고리 테이블의 menu_id는 메뉴 테이블에서 불러와야 한다.
이럴 때, 메뉴의 키값이자 카테고리 테이블의 참조키를 변수에 넣어줘서 가져온다.

#귀찮아서 그냥 다 import
from products.models import *

#메뉴에서 음료의 키값을 변수에 입력하기 위한 과정. id=1 메뉴=음료를 선택했을 때:
a1 = Menu.objects.get(id=1)
a1.save()	
a1

#결과
<Menu: Menu object (1)>


#카테고리에 Insert / 괄호안은 실제 DB의 컬럼명을 넣어준다
Category.objects.create(menu = a1, name = name='콜드브루커피')
Category.objects.create(menu = a1, name = name='브루드커피')
Category.objects.create(menu = a1, name = name='에스프레스')
Category.objects.create(menu = a1, name = name='푸라푸치노')
Category.objects.create(menu = a1, name = name='블렌디드')
Category.objects.create(menu = a1, name = name='스타벅스피지오')
Category.objects.create(menu = a1, name = name='티(티바나)')
Category.objects.create(menu = a1, name = name='기타 제조 음료')
Category.objects.create(menu = a1, name = name='스타벅스 주스(병음료)')

menu_id = m1 아니지?

Drinks도 Categories 1개만 참조중

c1 = Category.objects.get(id=1)
c2 = Category.objects.get(id=2)
c3 = Category.objects.get(id=3)

Drink.objects.create(korean_name="나이트로 바닐라 크림", english_name="Nitro Vanilla Cream", description="부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한번에 느껴보세요!", category = c1)
Drink.objects.create(korean_name="나이트로 쇼콜라 클라우드", english_name="Nitro Chocolat Cloud", description="초콜릿과 견과류의 풍미, 초콜릿 파우더 토핑, 하프&하프 샷, 부드럽고 달콤한 새로운 나이트로 콜드 브루", category = c1)
Drink.objects.create(korean_name="나이트로 콜드 브루", english_name="Nitro Cold Brew", description="나이트로 커피 정통의 캐스케이딩과 부드러운 콜드 크레마!, 부드러운 목 넘김과 완벽한 밸런스에 커피 본연의 단맛을 경험할 수 있습니다.", category = c1)
Drink.objects.create(korean_name="돌체 콜드 브루", english_name="Dolce Cold Brew", description="무더운 여름철, 동남아 휴가지에서 즐기는 커피를 떠오르게 하는 스타벅스의 음료의 베스트 x 베스트 조합인 돌체 콜드 블루를 만나보세요!", category = c1)
Drink.objects.create(korean_name="바닐라 크림 콜드 브루", english_name="Vanilla Cream Cold Brew", description="콜드 브루에 더해진 바닐라 크림으로 깔끔하면서 달콤한 콜드 브루를 새롭게 즐길 수 있는 음료입니다", category = c1)
Drink.objects.create(korean_name="제주 비자림 콜드 브루", english_name="Jeju Forest Cold Brew", description="제주 천년의 숲 비자림을 연상시키는 음료로 제주에서 유기농 말차로 만든 파우더와 Cold Brew를 활용한 음료. 더욱 시원하고 새로운 Cold Brew를 제주에서 즐겨보세요.", category = c1)
Drink.objects.create(korean_name="콜드 브루", english_name="Cold Brew", description="스타벅스 바리스타의 정성으로 탄생한 콜드 브루! 콜드 브루 전용 원두를 차가운 물로 14시간 동안 추출하여 한정된 양만 제공됩니다. 깊은 풍미의 새로운 커피 경험을 즐겨보세요.", category = c1)
Drink.objects.create(korean_name="콜드 브루 몰트", english_name="Cold Brew Malt", description="리저브 콜드 브루, 바닐라 아이스크림, 몰트가 블렌딩된 리저브만의 쉐이크", category = c1)
Drink.objects.create(korean_name="콜드 브루 플로트", english_name="COld Brew Float", description="리저브 콜드 브루 위에 녹아 내리는 한 스쿱의 바닐라 아이스크림", category = c1)
Drink.objects.create(korean_name="아이스 커피", english_name="Iced Cofee", description="깔끔하고 상큼함이 특징인 시원한 커피", category = c2)
Drink.objects.create(korean_name="오늘의 커피", english_name="Brewed Cofee", description="신선하게 브루드(Brewed)되어 원두의 다양함이 살아있는 커", category = c2)
Drink.objects.create(korean_name="블론드 토피 넛 라떼", english_name="Blonde Toffee Nut Latte", description="더 이상의 다른 설명은 필요 없는 스타벅스 정통의 오리지널 토피 넛 라떼를 블론드로 만나보세요.", category = c3)
Drink.objects.create(korean_name="아이스 블론드 토피넛 라떼", english_name="Iced Blonde Toffee Nut Latte", description="더 이상의 다른 설명은 필요 없는 스타벅스 정통의 오리지널 토피 넛 라떼를 블론드로 만나보세요.", category = c3)
Drink.objects.create(korean_name="아이스 토피 넛 라떼", english_name="Iced Toffee Nut Latte", description="더 이상의 다른 설명은 필요 없는 스타벅스 정통의 오리지널 토피 넛 라떼를 크리스마스 시즌 한정으로 만나보세요.", category = c3)

Nutrition

Nutritions.objects.create(one_serving_kca = 75, sodium_mg = 20, saturated_fat_g = 2, sugars_g = 10, protein_g = 1, caffeine_mg = 245, drink = Drink.objects.get(id=1), size = Size.objects.get(id=1))

Images

Image.objects.create(image_url="https://image.istarbucks.co.kr/upload/store/skuimg/2021/04/[9200000002487]_20210426091745609.jpg", drink = Drink.objects.get(id = 1))

Image.objects.create(image_url="https://image.istarbucks.co.kr/upload/store/skuimg/2021/04/[9200000000479]_20210426091844065.jpg", drink = Drink.objects.get(id = 3))

2가지 참조하는 객체 생성

g2 = Allergy.objects.get(id = 2)

Allergy_Drink.objects.create(allergy = Allergy.objects.get(id = 2), drink = Drink.objects.get(id = 4))
Allergy_Drink.objects.create(allergy = Allergy.objects.get(id = 2), drink = Drink.objects.get(id = 1)) 
Allergy_Drink.objects.create(allergy = Allergy.objects.get(id = 1), drink = Drink.objects.get(id = 5)) 

  • N:N 관계는 테이블 두개 중 하나에만 ManyToManyField를 설정해주면 되고 중간테이블을 만든다.
  • 'Drink'는 드링크와 다대다 관계를 의미하며 through는 Allergy_drink 테이블로 서로를 잇는다는 의미다.

0개의 댓글