django - 관계형 model 생성하기

whybein·2020년 2월 20일
0

django

목록 보기
7/13
post-thumbnail

스타벅스 데이터를 가지고 장고 모델을 만들어보도록 하겠습니다.

 

1. ForeignKey

 

https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey

Many-to-one 관계일 경우 ForeignKey를 사용합니다. 대분류는 여러개의 중분류를 가지지만, 중분류는 하나의 대분류만 가지기 때문에 Many-to-one 이라고 할 수 있습니다.

스타벅스의 대분류 모델이 있고 대분류를 참조하는 중분류 모델을 만들어 보겠습니다. 중분류의 두번째 필드는 대분류를 참조해 각 중분류가 어느 대분류에 속하는지 알 수 있게 해줍니다.

 

class MainCategory(models.Model):
    name       = models.CharField(max_length = 100)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

class SubCategory(models.Model):
    name          = models.CharField(max_length = 100)
    main_category = models.ForeignKey('MainCategory', on_delete = models.SET_NULL, null=True)
    created_at    = models.DateTimeField(auto_now_add = True)
    updated_at    = models.DateTimeField(auto_now = True)

 

  • 참조하려고 하는 대분류가 먼저 표기되어 있지 않다면 모델명을 ''로 감싸줘서 선언적 참조를 해줘야 합니다. 위와 같이 대분류가 먼저 있는 경우에는 'MainCategory'에서 ''가 없어도 됩니다.
  • foreignkey는 참조 필드의 id를 자동으로 가져오며 데이터베이스 필드명 뒤에 _id가 자동으로 붙게 됩니다.

 

on_delete 옵션

참조 객체가 지워질 경우의 옵션들입니다.

  • on_delete = models.CASCADE
    연결되어 있는 값도 함께 삭제됩니다.
    유저가 탈퇴하면 해당 유저가 쓴 글, 댓글이 모두 삭제됩니다.

  • on_delete = models.SET_NULL
    null = True 일 때만 가능한 옵션으로 NULL로 바뀝니다.
    유저가 탈퇴하면 해당 유저가 쓴 글의 작성자가 Anonymous로 바뀌는 식

  • on_delete = models.SET_DEFAULT
    설정해 놓은 defaul 값으로 바뀝니다.

그 밖에도 삭제를 제한하는 등의 다른 기능들이 있습니다.

 


2. ManyToManyField

이름 그대로 ManyToMany 관계일 때 이 필드를 사용합니다. 제품은 다양한 사이즈를 가지며 사이즈도 여러제품에 속성이 됩니다.

스타벅스의 제품 모델과 사이즈 모델이 있습니다. 각 제품은 solo, short, tall, grande, venti 등의 속성을 가지며 사이즈마다 가격이 달라집니다. 제품과 사이즈 조합에 따라 다른 가격을 가지기 때문에 manytomany로 가격 모델을 만들어보도록 하겠습니다. 가격은 제품과 사이즈를 참조하는 모델이 됩니다.

https://docs.djangoproject.com/en/dev/ref/models/fields/#manytomanyfield

 

# 최소한의 필드만 표기했습니다.
class Size(models.Model):
    name       = models.CharField(max_length = 100)

class Product(models.Model):
    main_category = models.ForeignKey(MainCategory, on_delete = models.SET_NULL, null=True)
    sub_category  = models.ForeignKey(SubCategory, on_delete = models.SET_NULL, null=True)
    name          = models.CharField(max_length = 100)
    size          = models.ManyToManyField(Size, through='Price')

class Price(models.Model):
    size       = models.ForeignKey(Size, on_delete = models.SET_NULL, null=True)
    product    = models.ForeignKey(Product, on_delete = models.SET_NULL, null=True)
    price      = models.DecimalField(max_digits = 10, decimal_places = 2, null=True)

제품의 대분류, 중분류 필드는 각각 대분류와 중분류를 참조합니다. 사이즈 모델은 각 사이즈 이름만을 갖고 있습니다.

  • 제품의 size 필드는 실제 DB에 존재하지 않습니다. (manytomany 필드의 속성)
  • 제품의 size는 각 제품마다 다르며 복수의 값을 가지는데 그 조합은 가격 모델에 있습니다.
  • through 옵션을 통해 중간 테이블을 지정합니다. (가격)
profile
Back-End Developer

0개의 댓글