프로젝트 명 : westarbucks
작업할 app명 : products
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length=20)
def __str__(self): # shell에서 보이는 정보
return f'{self.name}'
class Meta:
db_table = 'menu' # 실제 DB에 만들어지는 테이블 명
class Category(models.Model):
name = models.CharField(max_length=20)
menu = models.ForeignKey('Menu', on_delete=models.SET_NULL, null=True)
def __str__(self):
return f'{self.name}'
class Meta:
db_table = 'categories'
class Drink(models.Model):
category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
korean_name = models.CharField(max_length=45)
english_name = models.CharField(max_length=45)
description = models.TextField()
is_new = models.SmallIntegerField(default=0)
def __str__(self):
return f'{self.korean_name}'
class Meta:
db_table = 'drinks'
class Image(models.Model):
drink = models.ForeignKey('Drink', on_delete=models.CASCADE)
image_url = models.CharField(max_length=2000)
def __str__(self):
return f'{self.drink} : {self.image_url}'
class Meta:
db_table = 'images'
class Nutrition(models.Model):
drink = models.OneToOneField('Drink', on_delete=models.CASCADE)
size = models.CharField(max_length=20, null=True)
size_ml = models.IntegerField(null=True)
size_fluid_ounce = models.IntegerField(null=True)
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)
sugers_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)
def __str__(self):
return f'{self.drink} nutritions'
class Meta:
db_table = 'nutritions'
class Allergy(models.Model):
name = models.CharField(max_length=45)
def __str__(self):
return f'{self.name}'
class Meta:
db_table = 'allergies'
class AllergyDrink(models.Model):
allergy = models.ForeignKey('Allergy', on_delete=models.CASCADE)
drink = models.ForeignKey('Drink', on_delete=models.CASCADE)
def __str__(self):
return f'{self.drink} : {self.allergy}'
class Meta:
db_table = 'allergy_drink'
### 3. Shell에서 데이터 조회
-Django가 import된 python shell 실행
명렁어는 manage.py가 있는 폴더에서 (중요함)
> python manage.py shell
-데이터 insert (쉘창에서 했음)
Menu.objects.create(name="음료")
Category.objects.create(name="콜드 브루", menu_id=1)
Drink.objects.create(korean_name="나이트로 바닐라 크림", category_id=1)
** 중요한건 연결된 테이블에서는 설정된 관계에 따라 순차적으로 데이터를 넣어주는게 좋다.(메뉴>카테고리>음료)
예시1.
![](https://velog.velcdn.com/images/secret0831/post/93a1b8d5-71a3-47ad-b24c-1fc943df8a5d/image.png)
- 정참조(Forward)로 연결된 데이터 조회하기.(쉘에서 진행했음)
-- 정참조는 간편하게 점('.')으로 조회 가능하다.
예시) '나이트로 바닐라 크림'라는 음료가 속한 메뉴 이름 조회하기
drink = Drink.objects.get(id=1)
drink
<Drink: 나이트로 바닐라 크림>
drink.korean_name
'나이트로 바닐라 크림'
'나이트로 바닐라 크림'이 속한 카테고리 정보 조회
drink.category
<Category: 콜드 브루>
'나이트로 바닐라 크림'이 속한 카테고리의 이름만 조회
drink.category.name
'콜드 브루'
'나이트로 바닐라 크림'이 속한 카테고리가 속한 메뉴 정보 조회
drink.category.menu
<Menu: 음료>
'나이트로 바닐라 크림'이 속한 카테고리가 속한 메뉴의 이름만 조회
drink.category.menu.name
'음료'
역참조(Backward)로 연결된 데이터 조회하기
-- 해당 객체를 참조하고 있는 다른 객체가 ForeignKey를 가지고 있거나 다대다 관계인 경우, 해당 객체 기준에서 사용하는 방법이다. (누가 날 바라보고 있는지 모르는 쪽)
-- 즉, 부모테이블에서 자식 테이블의 특정 데이터를 조회할 때를 말한다.
Django에서 역참조를 할 수 있게 해주는 도구를 사용한다.
예시) id가 1인 메뉴를 참조하고 있는 음료 데이터 중 첫번째 데이터만 조회하기
menu = Menu.objects.get(id=1)
menu.category_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x7fde98116820>
해당 객체가 참조하는 객체명(소문자)_set은 reverse_many_to_one_manager라고 나온다.
즉, 역참조를 할 수 있게 해주는 도구이다.
id가 1인 메뉴를 참조하고 있는 카테고리의 모든 데이터 조회
menu.category_set.all()
<QuerySet [<Category: 콜드 브루>, <Category: 블렌디드>, <Category: 스타벅스 피지오>, <Category: 티(티바나)>]>
id가 1인 메뉴를 참조하고 있는 카테고리의 모든 데이터에서 첫번째 데이터만 조회
menu.category_set.all()[0]
<Category: 콜드 브루>
id가 1인 메뉴를 참조하고 있는 카테고리의 첫번째 데이터를 참조하고 있는 음료의 모든 데이터 조회
menu.category_set.all()[0].drink_set.all()
<QuerySet [<Drink: 나이트로 바닐라 크림>, <Drink: 나이트로 쇼콜라 클라우드>]>
id가 1인 메뉴를 참조하고 있는 카테고리의 첫번째 데이터를 참조하고 있는 음료에서 첫번째 데이터만 조회(이름만)
menu.category_set.all()[0].drink_set.all()[0].korean_name
'나이트로 바닐라 크림'