스타벅스 웹페이지 모델링한 것을 토대로 모델을 작성하고 데이터를 생성해 볼 것이다.
스타벅스 프로젝트를 생성하고 기본 환경설정을 해준다.
settings.py
설정 : INSTALLED_APPS
, MIDDLEWARE
에서 필요없는 것들은 주석처리 해준다. 데이터베이스와 시크릿키는 중요한 정보로 따로 관리해주는 것이 좋다.my_settings.py
생성과 설정 : manage.py
와 같은 경로에서 my_settings.py
를 만들어주고 여기에 데이터베이스와 시크릿키를 입력한다. settings.py
에서는 my_settings.py
의 데이터베이스와 시크릿키를 연결해준다.INSTALLED_APPS
에 추가한다.서버가 잘 동작하는지 체크해본다.
깃헙에 올리기 전에 중요하거나 불필요한 파일들은 .gitignore
에 입력해준다. my_settings.py
도 추가한다. 프로젝트를 로컬 레퍼지토리에 올린다. 깃헙 레퍼지토리를 생성 후 로컬 레퍼지토리와 연동시킨다.
git branch -M main
: 초기 branch가 master 라면 main 으로 변경해준다.이제 main branch에서의 작업은 끝났다. 다른 기능을 추가하고 싶다면 새로운 branch에서 작업하는 것이 좋다.
스타벅스 메뉴에 대한 브랜치 featrue/crud
와 앱 products
를 새로 생성한다. 앱이 추가된 것을 장고에게 알리기 위해, INSTALLED_APPS
에 products
를 추가한다. 이후 products/models.py
에서 모델링한 내용을 작성한다.
각각의 테이블은 클래스로 작성한다. 클래스가 어떻게 MySQL에서 테이블로 변환되는 것일까? 둘의 관계를 연동시키는 작업을 ORM 이라고 하고, 장고에서는 이를 자동으로 처리하여 우리가 할 작업을 줄여준다.
ORM Object Relational Mapping
객체와 테이블의 관계를 연결시켜주는 작업
ORM 참조
https://www.fullstackpython.com/object-relational-mappers-orms.html
모든 테이블을 설명하지 않고, 테이블 관계를 중점으로 몇가지 테이블만 살펴보자.
음료와 영양소. 1개의 음료 당 1개의 영양소가 존재한다. 서로 하나에만 연결되는 관계이다. 1:1 관계에서는 OneToOneField
속성을 사용한다. 둘 중 한 클래스에만 적용하면 된다. on_delete=models.CASCADE
는 참조하는 데이터가 삭제될 경우에 대한 옵션이다. 이 경우는 참조하는Products
데이터가 삭제되면 이와 연관된 Nutritions
데이터도 삭제된다.
메뉴와 카테고리. 1개의 메뉴에 대해 여러 개의 카테고리가 존재한다. 1:N 관계에서는 참조하는 클래스에서 ForienKey
속성을 적용한다.
음료와 알러지. 1개의 음료에 여러 개의 알러지가 있고, 여러 개의 음료에 1개의 알러지가 해당할 수 있다. N:N 관계를 정의하는 것은 2가지 방법이 있다.
1. 중간 테이블 생성
둘 중 한 클래스에 ManyToManyField
속성을 적용하고, through
에 중간 클래스 이름을 넣는다.
중간 클래스의 이름은 보통 클래스1_클래스2
로 정의한다. 그리고 연결될 2개의 클래스에 대해 각각 ForeignKey
를 적용한다.
2. 중간 테이블 없음
중간 테이블 없이 N:N 관계를 정의하려면, 한 클래스에 ManyToManyField
속성을 적용하고 다른 클래스 이름을 넣는다. 실제 데이터를 생성할 때에 그들의 관계가 실질적으로 연결된다.
# 음료와 알러지 테이블 정의
class Products(models.Model):
name = models.CharField(max_length=45)
.
.
class Allergies(models.Model):
name = models.CharField(max_length=45)
product = models.ManyToManyField(Products)
.
.
# django shell에서 음료와 알러지 데이터에 대해 변수와 save를 사용하여 생성한다.
p1 = Products(name="콜드 브루")
p1.save()
p2 = Products(name="카페 라떼")
p2.save()
a1 = Allergies(name="우유")
a1.save()
# 알러지 데이터 a1에 대해 음료 데이터 p1, p2를 다음과 같이 연결시킨다.
a1.products.add(p1)
a1.products.add(p2)
_id
를 붙이지 않아도 된다는 점. 처음에는 product_id
로 이름을 설정하였는데, 데이터베이스에는 product_id_id
로 중복되어 나타남. ORM 시 자동으로 붙여준다는 것을 알게 되고 필드명 다시 수정이러한 수정 사항을 반영한 후 다시 makemigrations
를 하니 모든 필드에 default 값을 입력하라는 메세지가 나왔다. 모델에 직접 작성하지 않은 id
도 입력해야 한다 해서, 마이그레이션 자체를 삭제하기로 결정했다.
나의 경우, 데이터베이스는 그대로 놔두고 테이블만 삭제하고 싶어서 MySQL에 다음과 같은 명령어를 입력했다.
SET @tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO @tables
FROM information_schema.tables
WHERE table_schema = 'DB이름 입력'
SET @tables = CONCAT('DROP TABLE ', @tables);
PREPARE stmt FROM @tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
데이터가 없는 빈 테이블이었기 때문에 가능했지만, defalut값을 입력하지 않고 마이그레이션을 수정할 수 있는 방법을 모색하는 것이 좋을 듯하다.