Django - model

양희연·2020년 6월 10일
0

Django

목록 보기
2/14
post-thumbnail

모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조를 말한다.

#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'
  • 기본키(ID)가 자동으로 추가된다.
  • 모델을 가져올 때 문자열을 사용하는 이유는 아직 정의되지 않은 모델을 참조하기 때문이다.
  • 다른 앱에서 모델을 참조할 때는 import 하지 않고 app.class_name
  • 장고는 외래키 필드명에 _id를 자동으로 추가한다.



🛠 migrate

모델을 작성하거나 수정한 경우 migrations 후 migrate 까지 진행해준다.

> makemigrations

모델 생성 또는 변경사항을 migration으로 저장시키고 싶다는 걸 장고에게 알려준다.

#product/migrations 폴더 안에 파일이 생성됨
(project) $ ./manage.py makemigrations product

#migrations 폴더에서 __init__.py 파일만 제외하고 삭제하는 명령어
(project) $ find . -path "*/migrations/*.py" -not -name "__init__.py" -delete

💡 makemigrations는 installed apps 에 등록된 앱만 적용된다.

> migrate

데이터베이스에 모델과 관련된 테이블을 생성한다.

아직 적용되지 않은 migrations를 모두 수집해 이를 실행하며, 이 과정을 통해 모델에서의 변경사항들과 데이터베이스의 스키마의 동기화가 이루어진다.

💡 모델 수정 시 null=True 에서 null 값을 허용하지 않게 수정 후 migration 하면 error가 발생한다.
     기본값을 설정해주라고 요청하면 기본값을 None으로 지정해주면 된다.




⛓ 정참조 & 역참조

➡️ 정참조: 화살표 방향 (필드에서 해당 모델로 가는 방향) 필드명
⬅️ 역참조: 화살표 역방향 모델명(소문자)_set

> ForeignKey

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>]>

> ManyToMany

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으로 자동 생성된다.

> ForeignKey

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')

> ManyToMany

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()
profile
꾸준히 나아가자!

0개의 댓글