모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조를 말한다.
#models.py
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length = 50)
#__str__: 인스턴스 자체를 출력할 때의 형식을 지정해주는 함수
#<QuerySet [<Menu: drink>]> 형식으로 반환됨
def __str__(self):
return self.name
#테이블명으로 복수형이어야 한다.
class Meta:
db_table = 'menus'
class Category(models.Model):
name = models.CharField(max_length = 50)
menu = models.ForeignKey('Menu', on_delete = models.SET_NULL, null = True)
def __str__(self):
return self.name
class Meta:
db_table = 'categories'
app.class_name
_id
를 자동으로 추가한다.모델을 작성하거나 수정한 경우 migrations 후 migrate 까지 진행해준다.
모델 생성 또는 변경사항을 migration으로 저장시키고 싶다는 걸 장고에게 알려준다.
#product/migrations 폴더 안에 파일이 생성됨
(project) $ ./manage.py makemigrations product
#migrations 폴더에서 __init__.py 파일만 제외하고 삭제하는 명령어
(project) $ find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
💡 makemigrations는 installed apps 에 등록된 앱만 적용된다.
데이터베이스에 모델과 관련된 테이블을 생성한다.
아직 적용되지 않은 migrations를 모두 수집해 이를 실행하며, 이 과정을 통해 모델에서의 변경사항들과 데이터베이스의 스키마의 동기화가 이루어진다.
💡 모델 수정 시
null=True
에서 null 값을 허용하지 않게 수정 후 migration 하면 error가 발생한다.
기본값을 설정해주라고 요청하면 기본값을None
으로 지정해주면 된다.
➡️ 정참조: 화살표 방향 (필드에서 해당 모델로 가는 방향) 필드명
⬅️ 역참조: 화살표 역방향 모델명(소문자)_set
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length = 50)
def __str__(self):
return self.name
class Meta:
db_table = 'menus'
class Category(models.Model):
name = models.CharField(max_length = 50)
menu = models.ForeignKey('Menu', on_delete = models.SET_NULL, null = True)
def __str__(self):
return self.name
class Meta:
db_table = 'categories'
👇 django shell 진입 👇
(project) $ ./manage.py shell
#정참조
#Category → Menu
#categories 테이블에서 id가 1인 객체의 메뉴 이름을 알고 싶을 때
cold_brew = Category.objects.get(id=1)
cold_brew.menu.name
'drink'
#역참조
#Menu → Category
#menus 테이블에서 id가 1인 객체를 참조하는 모든 카테고리 이름을 알고 싶을 때
drink = Menu.objects.get(id=1)
drink.category_set.all()
<QuerySet [<Category: cold brew>, <Category: espresso>, <Category: americano>]>
class Drink(models.Model):
name = models.CharField(max_length = 50)
allergy = models.ManyToManyField('Allergy', through = 'AllergyDrink')
class Meta:
db_table = 'drinks'
class Allergy(models.Model):
name = models.CharField(max_length = 50)
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)
class Meta:
db_table = 'allergies_drinks'
👇 django shell 진입 👇
(project) $ ./manage.py shell
#정참조
#Drink → Allergy
#drinks 테이블에서 id가 1인 객체가 갖고 있는 모든 알러지 데이터를 알고 싶을 때
d = Drink.objects.get(id=1)
d.allergy.all()
<QuerySet [<Allergy: Allergy object (1)>, <Allergy: Allergy object (2)>]>
#역참조
#Allergy → Drink
#allergies 테이블에서 id가 1인 객체가 갖고 있는 모든 음료 데이터를 알고 싶을 때
a = Allergy.objects.get(id=1)
a.drink_set.all()
<QuerySet [<Drink: Drink object (1)>, <Drink: Drink object (2)>]>
장고에서 모델 작성 시 foreignkey를 설정할 때 related_name도 설정해주면 데이터 조회 시 편리한다.
related_name을 설정하지 않으면 모델명(소문자)_set
으로 자동 생성된다.
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length = 50)
def __str__(self):
return self.name
class Meta:
db_table = 'menus'
class Category(models.Model):
name = models.CharField(max_length = 50)
menu = models.ForeignKey('Menu', on_delete = models.SET_NULL, null = True, related_name = 'category')
def __str__(self):
return self.name
class Meta:
db_table = 'categories'
👇 django shell 진입 👇
(project) $ ./manage.py shell
#역참조
#Menu → Category
#menus 테이블에서 id가 1인 객체를 참조하는 모든 카테고리 이름을 알고 싶을 때
drink = Menu.objects.get(id=1)
#기존
drink.category_set.all()
#related_name
drink.category.all()
#related_name을 이용하여 자신을 참조하는 객체 생성
#이 경우 외래키는 지정해줄 필요 없다.
drink.category.create(name = 'americano')
from django.db import models
class Drink(models.Model):
name = models.CharField(max_length = 50)
allergy = models.ManyToManyField('Allergy', through = 'AllergyDrink', related_name = 'drink')
class Meta:
db_table = 'drinks'
class Allergy(models.Model):
name = models.CharField(max_length = 50)
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)
class Meta:
db_table = 'allergies_drinks'
👇 django shell 진입 👇
(project) $ ./manage.py shell
#역참조
#Allergy → Drink
#allergies 테이블에서 id가 1인 객체가 갖고 있는 모든 음료 데이터를 알고 싶을 때
a = Allergy.objects.get(id=1)
#기존
a.drink_set.all()
#related_name
a.drink.all()