TIL42. Django : Westarbucks C.R.U.D - 1

ID짱재·2021년 10월 17일
3

Django

목록 보기
33/43
post-thumbnail

📌 이 포스팅에서는 westatbucks ERM 모델링을 참고하여 Django의 Model을 작성하는 과정에 대해 정리하였습니다.



🌈 Westarbucks C.R.U.D - 1

🔥 Model 파악하기

🔥 Model 생성하기

🔥 Create : Data 삽입



1. Model 파악하기

🤔 ERM 모델링 구조 확인

✔️ 목표 사이트 주소 : https://www.starbucks.co.kr/menu/drink_list.do
✔️ ERM 구성도

🤔 Application 생성 및 등록

✔️ 앱을 생성하는 명령어는 startapp이다. 복수형으로 앱이름을 지정해주는 것이 권장된다.

$ python manage.py startapp [앱이름]
ex) $ python manage.py startapp products 👈 products앱 생성

✔️ 앱을 생성하였다면 등록해주어야 한다. 앱을 등록하지 않으면, Django에서 인식하지 못한다.
✔️ 앱을 등록시키는 방법은 간단하다. settgins.py에 앱이름만 등록해주면 된다.
✔️ "DJANGO_APPS", "PROJECT_APPS", "THIRD_PARTY_APPS"로 앱을 분리시킨 이유는 추후 복잡성을 낮추기 위함이다. 생성한 앱이나, 외부에서 설치하는 앱이 많지 않다면 분리시킬 필요가 없다.

# Application definition
DJANGO_APPS = [
    # "django.contrib.admin",
    # "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
]
PROJECT_APPS = [
    "products", # 👈 products 앱을 등록합니다.
]
THIRD_PARTY_APPS = [
    "corsheaders",
]
INSTALLED_APPS = DJANGO_APPS + PROJECT_APPS + THIRD_PARTY_APPS


2. Model 생성하기

🤔 models.py란?

✔️ products 앱을 생성하면 models.py는 자동으로 만들어져 있다. 이 곳에 테이블, 필드 등을 지정하고, 테이블간 relationship을 맺어주면 ORM구성도와 같이 모델을 구축할 수 있다.
✔️ Django뿐 아니라, 많은 프레임워크는 ORM을 지원하기 때문에 python 코드로 DB구축을 제어할 수 있어서 직접 SQL문을 작성하지 않아도 되기 때문에 간편하다.
✔️ models을 구성할 때는 class로 만들고, 이미 프레임워크에서 제공되는 models을 상속받아 사용한다.

from django.db import models
class FirstModel(models.Model): # 👈 table 이름이 FirstModel일 때,
    pass

🤔 table 생성하기

✔️ table은 Menu, Category, Product, Nutrition, Allergy, Image 테이블과 중계모델로 Allergy 테이블과 Product 테이블을 중계해주는 AllergyProduct을 생성했다.
✔️ 테이블을 생성할 때는 ForeignKey field가 필요하지 않은 모델부터 생성해서 점차 연결시켜나가면 구축하기 편하다.
✔️ Meta클래스를 통해 db_table의 이름을 지정하면, mysql에서 해당 이름으로 table이 생성된다.

# 🚀 Menu Table
from django.db import models
class Menu(models.Model):
    name = models.CharField(max_length=45)
    class Meta:
        db_table = "menu"
# 🚀 Category Table        
class Category(models.Model):
    name = models.CharField(max_length=45)
    menu = models.ForeignKey("menu", on_delete=models.CASCADE)
    class Meta:
        db_table = "categories"
# 🚀 Product Table        
class Product(models.Model):
    name = models.CharField(max_length=45)
    category = models.ForeignKey("Category", on_delete=models.CASCADE)
    nutrition = models.ForeignKey("Nutrition", on_delete=models.CASCADE)
    allergy = models.ManyToManyField("Allergy", through="AllergyProduct")
    class Meta:
        db_table = "products"
# 🚀 Nutrition Table        
class Nutrition(models.Model):
    kcal = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    sodium = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    fat = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    sugar = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    protein = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    caffeine = models.DecimalField(max_digits=5, decimal_places=2, default=0, null=True)
    class Meta:
        db_table = "nutritions"
# 🚀 Allergy Table        
class Allergy(models.Model):
    name = models.CharField(max_length=45)
    class Meta:
        db_table = "allergies"
# 🚀 AllergyProduct Table        
class AllergyProduct(models.Model):
    product = models.ForeignKey("Product", on_delete=models.CASCADE)
    allergy = models.ForeignKey("Allergy", on_delete=models.CASCADE, null=True)
    class Meta:
        db_table = "allergies_products"
# 🚀 Image Table        
class Image(models.Model):
    image_url = models.CharField(max_length=2000)
    product = models.ForeignKey("Product", on_delete=models.CASCADE)
    class Meta:
        db_table = "images"

🤔 makemigration && migrate

✔️ 모델을 구성햇다면, 이를 통해 MySQL에 모델을 생성해주기 위해 2가지 명령이 필요하다.
✔️ 이를 makemigration과 migrate이다. 한번에 명령하는 방법은 아래와 같다.
✔️ models.py의 변경이 일어났다면, 이 명령어를 잊지 말고 실행시켜주자.

$ python manage.py makemigration && python manage.py migrate

🤔 Mysql 반영사항 확인하기

✔️ 터미널에서 Mysql에 접속한하여 확인할 DB를 선택한다.

$ mysql -u root -p 👈 login
$ show databases; 👈 DB목록 조회
$ use [목록 중 확인할 db명]; 👈 DB 선택

✔️ 해당 DB에 생성된 table을 확인한다.

$ show tables; 👈 DB 선택
& desc [확인할 table명] 👈 table이 어떤 구조로 생성되었는지 보여준다.

✔️ 해당 table의 데이터 확인은 아래와 같다. 데이터가 있어야 확인된다.

& select * from [확인할 table명]

✔️ 모든 컬럼(필드)이 아닌 일부만 조회하고 싶다면 아래와 같이 할 수 있다.

& select [field명, field명, field명...] from [확인할 table명]

✔️ 데이터를 삽입하다보면 잘못 저장되는 생성되는 실수가 발생한다. 해당 row만 삭제하면 순번 건너띄기가 발생하기 때문에 필요에 따라 table을 초기화하고 싶을 때가 있다. 이럴 때는 아래 명령으로 가능하다.

& truncate [table명] 👈 table을 삭제하고 다시 생성해주는 명령을 한번에 가능하게 해준다.

✔️ 해당 table에 ForeignKey가 존재가 존재하거나, 참조받고 있다면 이러한 "ERROR 1701 (42000)"가 발생한다. mysql에서 보호를 목적으로 lock을 걸어둔거 같다.
✔️ 이럴 때는 외래키 체크 해제를 해주고 해당 명령어를 사용해주면 정상적으로 동작한다. 테이블을 초기화하고 다시 외래키를 활성화시키는게 안전하다.

& SET FOREIGN_KEY_CHECKS = 0; 👈 외래키 체크 해제
$ SET FOREIGN_KEY_CHECKS = 1; 👈 외래키 체크 설정



3. Create : Data 삽입

🤔 python shell에서 data 삽입

✔️ DB에 data를 삽입하기 위해서 Django shell에 진입합니다.

& python manage.py shell

✔️ Menu Table data 삽입

# python manage.py shell
>>> Menu.objects.create(name="음료")
>>> Menu.objects.create(name="푸드")
>>> Menu.objects.create(name="상품")
>>> Menu.objects.create(name="카드")

✔️ Category Table data 삽입

# python manage.py shell
>>> m1 = Menu.objects.get(id=1)
>>> m2 = Menu.objects.get(id=2)
>>> Category.objects.create(name="콜드 브루", menu_id=m1)
>>> Category.objects.create(name="브렌디드", menu_id=m1)
>>> Category.objects.create(name="브레드", menu_id=m2)
>>> Category.objects.create(name="케이크", menu_id=m2)

✔️ Nutrition Table data 삽입

# python manage.py shell
>>> Nutrition.objects.create(kcal=75, sodium=20, fat=2, sugar=10, protein=1, caffeine=245)
>>> Nutrition.objects.create(kcal=5, sodium=5, caffeine=245)
>>> Nutrition.objects.create(kcal=120, sodium=70, fat=0, sugar=25, protein=1, caffeine=35)
>>> Nutrition.objects.create(kcal=370, sodium=105, fat=4.3, sugar=57, protein=9)
>>> Nutrition.objects.create(kcal=468, sodium=487, fat=13, sugar=16, protein=8)
>>> Nutrition.objects.create(kcal=395, sodium=270, fat=12, sugar=11, protein=4)
>>> Nutrition.objects.create(kcal=375, sodium=340, fat=4, sugar=18, protein=5)

✔️ Product Table data 삽입

# python manage.py shell
>>> c1 = Category.objects.get(id=1)
>>> c2 = Category.objects.get(id=2)
>>> c3 = Category.objects.get(id=3)
>>> c4 = Category.objects.get(id=4)
>>> n1 = Nutrition.objects.get(id=1)
>>> n2 = Nutrition.objects.get(id=2)
>>> n3 = Nutrition.objects.get(id=3)
>>> n4 = Nutrition.objects.get(id=4)
>>> n5 = Nutrition.objects.get(id=5)
>>> n6 = Nutrition.objects.get(id=6)
>>> n7 = Nutrition.objects.get(id=7)
>>> Product.objects.create(name="나이트로 바닐라 크림", description="생략", category_id=c1, nutrition_id=n1)
>>> Product.objects.create(name="나이트로 콜드 브루", description="생략", category_id=c1, nutrition_id=n2)
>>> Product.objects.create(name="망고 패션 프로트 브렌디드", description="생략", category_id=c2, nutrition_id=n3)
>>> Product.objects.create(name="딸기 딜라이트 요거트 브렌디드", description="생략", category_id=c2, nutrition_id=n4)
>>> Product.objects.create(name="미니 클래식 스콘", description="생략", category_id=c3, nutrition_id=n5)
>>> Product.objects.create(name="밀당 에그 타르트", description="생략", category_id=c4, nutrition_id=n6)
>>> Product.objects.create(name="밀당 초코 타르트", description="생략", category_id=c4, nutrition_id=n7)

✔️ Image Table data

# python manage.py shell
>>> p1 = Product.objects.get(id=1)
>>> p2 = Product.objects.get(id=2)
>>> p3 = Product.objects.get(id=3)
>>> p4 = Product.objects.get(id=4)
>>> p5 = Product.objects.get(id=5)
>>> p6 = Product.objects.get(id=6)
>>> p7 = Product.objects.get(id=7)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p1)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p2)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p3)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p4)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p5)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p6)
>>> Image.objects.create(image_url="이미지 경로 복사 주소", product_id=p7)

✔️ Allergy Table data

# python manage.py shell
>>> Allergy.objects.create(name="대두")
>>> Allergy.objects.create(name="우유")
>>> Allergy.objects.create(name="난류")
>>> Allergy.objects.create(name="밀")
>>> Allergy.objects.create(name="아항산류")
>>> Allergy.objects.create(name="토마토")

✔️ AllergyProduct Table data

# python manage.py shell
>>> a1 = Allergy.object.get(id=1)
>>> a2 = Allergy.object.get(id=2)
>>> a3 = Allergy.object.get(id=3)
>>> a4 = Allergy.object.get(id=4)
>>> a5 = Allergy.object.get(id=5)
>>> a6 = Allergy.object.get(id=6)
>>> p1 = Product.objects.get(id=1)
>>> p2 = Product.objects.get(id=2)
>>> p3 = Product.objects.get(id=3)
>>> p4 = Product.objects.get(id=4)
>>> p5 = Product.objects.get(id=5)
>>> p6 = Product.objects.get(id=6)
>>> p7 = Product.objects.get(id=7)
>>> AllergyProduct.objects.create(allergy_id=a2, product_id=p1)
>>> AllergyProduct.objects.create(allergy_id=a2, product_id=p4)
>>> AllergyProduct.objects.create(allergy_id=a2, product_id=p5)
>>> AllergyProduct.objects.create(allergy_id=a3, product_id=p5)
>>> AllergyProduct.objects.create(allergy_id=a4, product_id=p5)
>>> AllergyProduct.objects.create(allergy_id=a2, product_id=p6)
>>> AllergyProduct.objects.create(allergy_id=a3, product_id=p6)
>>> AllergyProduct.objects.create(allergy_id=a1, product_id=p6)
>>> AllergyProduct.objects.create(allergy_id=a1, product_id=p7)
>>> AllergyProduct.objects.create(allergy_id=a2, product_id=p7)
>>> AllergyProduct.objects.create(allergy_id=a3, product_id=p7)
>>> AllergyProduct.objects.create(allergy_id=a4, product_id=p7)
profile
Keep Going, Keep Coding!

1개의 댓글

comment-user-thumbnail
2021년 10월 17일

역시 최고

답글 달기