TIL68. django starbucks 모델링

Jaeyeon·2021년 3월 28일
0
post-thumbnail

Aquery를 이용한 모델링

스타벅스 모델링 django models.py

from django.db import models

class Menu(models.Model):
    name = models.CharField(max_length=20)
    class Meta:
        db_table = 'menu'
		

class Category(models.Model):
    name = models.CharField(max_length=20)
    menu = models.ForeignKey('Menu', on_delete=models.CASCADE)
    class Meta:
        db_table = 'category'
        
class Drink(models.Model):
    korean_name = models.CharField (max_length= 45)
    english_name = models.CharField(max_length = 45)
    description = models.TextField(max_length = 2000)
    category = models.ForeignKey('Category', on_delete=models.CASCADE)
    class Meta:
        db_table = 'Drink'
        
class Image(models.Model):
    image_url = models.URLField(max_length = 2000)
    drink = models.ForeignKey('Drink', on_delete = models.CASCADE)
    class Meta:
        db_table = 'image'
        
class Allergy(models.Model):
    name = models.CharField(max_length=45)
    drink = models.ManyToManyField('Drink',through ='Allergy_drink')
    class Meta:
        db_table = 'allergy'
        
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 Nutrition(models.Model):
    one_serving_kcal = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    sodium_mg = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    saturated_fat_g = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    sugars_g = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    protein_g = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    caffeine_mg = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    size_ml = models.CharField(max_length=45)
    size_fluid_ounce = models.CharField(max_length=45)
    drink = models.OneToOneField('Drink', on_delete=models.CASCADE)
    class Meta:
        db_table = 'nutrition'

하나하나 분석해보기

1-1. class Menu models.py

class Menu(models.Model):
    name = models.CharField(max_length=20)	# 이름의 형태는 문자열로 할 것이며 최대 길이는 20으로 설정
    class Meta:
        db_table = 'menu'			# 데이터베이스 테이블이름은 menu로 설정 해놓을 것이다.

1-2. class Menu API

>>> Menu.objects.create(name = '음료')
<Menu: Menu object (1)>

2-1. class Category

class Category(models.Model):
    name = models.CharField(max_length=20)
    menu = models.ForeignKey('Menu', on_delete=models.CASCADE)		# Menu를 참조하며 테이블에 나올때는 menu_id로 나온다. 여기서는 _id생략 된다. 메뉴가 삭제되면 카테고리도 삭제
    class Meta:
        db_table = 'category'

2-2 . class Category API

>>> a1 = Menu.objects.get(id=1)
>>> a1.name
'음료'
>>> a1
<Menu: Menu object (1)>
>>> Category.objects.create(name = '콜드 브루', menu =a1)
<Category: Category object (1)>
변수를 이용해서 참조할 수 있지만
>>> Categoty.objects.create(name = '콜드 브루', menu = Menu.objects.get(id =1)
<Category: Category object (1)>
위처럼 바로 넣어도 상관 없다.

새로 알게 된것

  • N:1 관계에서는 N이 1을 참조하는 방식으로 모델링해야한다.
  • N:1 관계는 Foreign key로 설정 하면된다.

3-1. class Drink

class Drink(models.Model):
    korean_name = models.CharField (max_length= 45)				# 한글이름 45자 글자제한
    english_name = models.CharField(max_length = 45)				# 영어이름 45자 글자제한
    description = models.TextField(max_length = 2000)				# 설명 2000자 제한
    category = models.ForeignKey('Category', on_delete=models.CASCADE)		# Category를 참조하며 카테고리가 없어지면 드링크도 없어진다.
    class Meta:
        db_table = 'Drink'

3-2. class Drink API

>>> a1 = Category.objects.get(id=1)
>>> a1
<Category: Category object (1)>
>>> Drink.objects.create(korean_name = '나이트로 바닐라 크림', english_name='Nitro Vanilla Cream',description = '부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한번에 느껴보세요!',category = a1)
<Drink: Drink object (1)>

4-1. class Image

class Image(models.Model):
    image_url = models.URLField(max_length = 2000)			# url필드를 사용했으며 2000자 제한
    drink = models.ForeignKey('Drink', on_delete = models.CASCADE)	# 이미지 여러개가 음료하나에 들어갈 수 있기 때문에 N:1 로 드링크를 참조, 드링크가 사라지면 이미지도 사라진다.
    class Meta:
        db_table = 'image'

4-2. class Image API

>>> a2 = Drink.objects.get(id=2)
>>> a2
<Drink: Drink object (2)>
>>> Image.objects.create(image_url = 'https://image.istarbucks.co.kr/upload/store/skuimg/2021/02/[9200000003273]_20210217102625012.jpg', drink = a2)
<Image: Image object (2)>

5-1. class Allergy

class Allergy(models.Model):
   name = models.CharField(max_length=45)				# 알러지 이름은 45자 제한
   drink = models.ManyToManyField('Drink',through ='Allergy_drink')	# 드링크와 N:N 관계이기 때문에 중간테이블을 세팅 했으며 중간 테이블은 Allergy_drink 이다.
   class Meta:
       db_table = 'allergy'

5-2. class Allergy API

>>> Allergy.objects.create(name = '우유')
<Allergy: Allergy object (1)>

새로 알게 된것

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

6-1. class Allergy_drink

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'

6-2. class Allergy_drink API

>>> Allergy_drink.objects.create(allergy = Allergy.objects.get(id = 3), drink = Drink.objects.get(id = 3))
<Allergy_drink: Allergy_drink object (3)>

새로 알게 된것

  • 중간테이블은 데이터를 각각 끌어와서 중간테이블에서 정리하는 방식이다.
  • 그러므로 두개의 테이블을 모두 참조하는 것이고 그게 공식이다.

7-1. class Nutrition

class Nutrition(models.Model):
    one_serving_kcal = models.DecimalField(max_digits=6, decimal_places=2, null=True)			# 칼로리는 소수점으로 표현하며 소수점 아래 숫자 포함 6글자까지 표현되며 소수점은 2자리까지표시된다.
    sodium_mg = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    saturated_fat_g = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    sugars_g = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    protein_g = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    caffeine_mg = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    size_ml = models.CharField(max_length=45)								 # ml수는 문자열로 입력되며 45자 제한
    size_fluid_ounce = models.CharField(max_length=45)
    drink = models.OneToOneField('Drink', on_delete=models.CASCADE)					 # 드링크와 1:1 로 연결되며 드링크가 사라지면 뉴트리션도 사라진다.
    class Meta:
        db_table = 'nutrition'

7-2. class Nutrition API

>>> Nutrition.objects.create(one_serving_kcal = 75, soldium_mg = 20, saturated_fat_g = 2, sugars_g = 10, protein_g = 1, caffeine_mg = 245, size_ml = 500, size_fluid_ounce = 12, drink = Drink.objects.get(id=1))

새로 알게 된것

  • 1:1 관계는 OneToOneField로 이어주면 된다.
  • OneToOneField는 참조가 되지 않을 때가 있으므로 ForeignKey로 설정하는 것도 방법이다 (경훈님)
profile
생각하는 개발자 되기

1개의 댓글