[TIL] Django CRUD2

Jene Hojin Choi·2021년 1월 30일
0

Django

목록 보기
2/12
post-thumbnail

Introduction to CRUD 2

저번 CRUD1 실습에서는 models.py를 다루었다.
주어진 간단한 과제를 해결하기 위해서 menu, category, product만 포함되어있는 모델을 만들었다.

하지만 이번에는 아래 사진에 주어진대로 menu, categories, drinks, images, allergy, allergy_drink, nutrition 까지 models.py 에 구현해보겠다.

Table of Contents

  1. models.py 작성
    1-1. ManyToManyField 파헤치기
  2. models.py 완성
  3. python shell: 음료 하나에 알러지 여러개 넣는법

1. models.py 작성

from django.db import models

django.db에서 제공하는 models 라는 모듈을 쓰기 위해 import를 해준다.

위의 AqueryTool에서 주어진 데이터베이스 모델을 보면 drink가 category를 참조하고, category가 menu를 참조한다. 즉, menu를 먼저 만들어야한다.

  • class Meta를 이용하여 mySQL의 database인 products에서 테이블 이름이 menu로 설정되도록 하였다.

(이걸 설정 해주지 않으면 테이블 이름은 자동으로 '데이터베이스 이름_클래스 이름'으로 설정된다. 즉, 여기서는 products_menu가 된다.)

  • ForeignKey를 이용하여 AQueryTool에서처럼 categories가 menu를 참조할 수 있도록 하였다.
  • menu_id 가 아니고 menu = models.ForeignKey('Menu', on_delete=models.CASCADE) 이다.
    menu_id 아니다!!!!!
  • class Meta를 써서 데이터 베이스에서 테이블 이름이 products_category 대신에 categories가 되도록 했다.

1-1. ManyToManyField

데이터베이스 모델을 다시 한번 살펴보자.
drink는 allergy와 many to many 관계이고, 그렇기 때문에 allergy_drink 라는 가운데 테이블이 존재한다.
이것을 models.py 에서 어떻게 구현할 수 있을까?

답은 ManyToManyField를 사용하는 것이다!

✅ ManyToManyField를 사용하지 않는다면

  • 중간 테이블 allergy_drink를 만들고, allergy, drink 각각에 foreignkey를 물어주어야한다.

✅ ManyToManyField를 사용한다면

  • 원래는 중간 테이 블을 따로 만들지 않아도 Django가 알아서 AllergyDrink 라는 테이블을 만들어준다!!!!!
  • 하지만 through 를 이용해서 어떤 테이블이 중간 테이블인지 명시해주는 것이 대체로 좋다.
    위의 소스코드에서는 중간 테이블을 만들어주고 allergy_drink 라고 이름도 지어주었다.

✅ ManyToManyField를 사용해야하는 이유

위에서 중간 테이블을 만들어주는 것이 대체로 좋다고 했는데, 그렇다면 왜 ManyToManyField 를 쓰는 것이 좋다고 하는 것일까? 쓰나 안 쓰나 별 차이가 없어보이니 말이다.

  • 알아서 중간 테이블을 만들어주는 장점이 있다. 하지만 위와 같은 간단한 예제의 경우 사실 중간 테이블이 크게 필요하지 않다.
  • 확장성이 있다. 데이터 모델을 변경하게 될때 (예를 들어 추가적인 column을 만든다던지) ManyToManyField 가 있는 것이 더 유용하다.

2. models.py 완성본

3. Challenge: many to many 관계의 데이터 여러개 넣기

Q. 나이트로 콜드 브루에 알러지 2개 (우유, 두유)를 추가해주고 싶다면?

  • 제주 쑥떡 크림 프라푸치노만 알러지가 3개 있고, 나이트로 콜드 브루는 알러지가 없는 상황이다.
  • 두유 객체는 존재하지도 않는다.

현재 상황은 이렇다:

mysql> SELECT * FROM drinks;
+----+--------------------------------------+-------------+
| id | name                                 | category_id |
+----+--------------------------------------+-------------+
|  1 | 제주 쑥떡 크림 프라푸치노                  |           1 |
|  2 | 나이트로 콜드 브루                       |           2 |
+----+--------------------------------------+-------------+

mysql> SELECT * FROM allergy;
+----+--------+
| id | name   |
+----+--------+
|  1 | 우유    |
|  2 | 대두    |
|  3 | 밀     |
+----+--------+

mysql> SELECT * FROM allergy_drink;
+----+------------+----------+
| id | allergy_id | drink_id |
+----+------------+----------+
|  1 |          1 |        1 |
|  2 |          2 |        1 |
|  3 |          3 |        1 |
+----+------------+----------+

drink객체.allergy.add(allergy객체1, allergy객체2)

결과:

mysql> SELECT * FROM allergy_drink;
+----+------------+----------+
| id | allergy_id | drink_id |
+----+------------+----------+
|  1 |          1 |        1 |
|  2 |          2 |        1 |
|  3 |          3 |        1 |
|  4 |          1 |        2 |
|  5 |          4 |        2 |
+----+------------+----------+

mysql> SELECT * FROM allergy;
+----+--------+
| id | name   |
+----+--------+
|  1 | 우유   |
|  2 | 대두   |
|  3 | 밀     |
|  4 | 두유   |
+----+--------+

0개의 댓글