오늘 해 볼 것은
1. Django Model로 Database table 생성
2. Django Shell에서 C.R.U.D (생성, 조회, 수정, 삭제)
이다.
그 전에 C.R.U.D
가 무엇인지 살펴 보고 가자
C.R.U.D
란, 대부분의 컴퓨터 소프트웨어가 갖는 기본적인 데이터 기능을 묶어서 일컫는 말이다.Create
, Read
, Update
, Delete
(생성, 조회, 수정, 삭제)이다.View
에서 Model
로 가는 과정이다.원하는 데이터를 새로 생성하고자 할 때 쓰인다.
class Size(models.Model):
name = models.CharField(max_length=40)
size_ml = models.CharField(max_length=40, null=True)
size_fluid_ounce = models.CharField(max_length=40, null=True)
class Meta:
db_table = 'sizes'
Size.objects.create(name='Tall(톨)', size_ml=355, size_fluid_ounce=12)
mysql> select * from sizes;
+----+-------------------+---------+------------------+
| id | name | size_ml | size_fluid_ounce |
+----+-------------------+---------+------------------+
| 1 | Tall(톨) | 355 | 12 |
+----+-------------------+---------+------------------+
objects
는 Model class를 통하여 Database에 Data를 C.R.U.D
작업을 제공하는 manager class
이다.create
는 manager class의 method
로, 해당 method가 호출되면 Database에 Query 작업
을 수행한다.즉, 파이썬 객체의 형태로 Database에 Data를 C.R.U.D하는 것이다.
원하는 데이터만 찾고자 할 때 쓰인다.
Product.objects.get(id=1) # id가 1인 것만 찾기
<Product: Product object (1)> # 해당 결과
Product.objects.filter(allergy=1) # product 중에서 allergy가 1(대두)인 것만 찾기
<QuerySet [<Product: Product object (1)>, <Product: Product object (12)>]> # 해당 결과
원하는 데이터를 수정하고자 할 때 쓰인다.
Tall(톨)
사이즈를 먼저 입력하고 Short(숏)
사이즈를 이후에 입력하여 id 순서가 Tall(톨)
이 먼저 와버렸다.mysql> select * from sizes;
+----+-------------------+---------+------------------+
| id | name | size_ml | size_fluid_ounce |
+----+-------------------+---------+------------------+
| 1 | Tall(톨) | 355 | 12 |
| 2 | Short(숏) | 237 | 8 |
+----+-------------------+---------+------------------+
update
를 사용하여 둘의 정보를 바꿔 보기 편하게 바꾸었다.Size.objects.filter(id=1).update(name='Short(숏)', size_ml=237, size_fluid_ounce=8)
Size.objects.filter(id=2).update(name='Tall(톨)', size_ml=355, size_fluid_ounce=12)
mysql> select * from sizes;
+----+-------------------+---------+------------------+
| id | name | size_ml | size_fluid_ounce |
+----+-------------------+---------+------------------+
| 1 | Short(숏) | 237 | 8 |
| 2 | Tall(톨) | 355 | 12 |
+----+-------------------+---------+------------------+
원하는 데이터를 삭제하고자 할 때 쓰인다.
Update
상황 대신, Delete
를 사용하여 데이터를 삭제하고 다시 입력할 수도 있다.Size.objects.filter(id=1).delete()
Django Shell
을 편하고 깔끔하게 이용하고자 ipython
을 이용하고자 한다.
일단 iptyhon
을 설치해 보자.
pip install ipython
이후 database의 application 생성 한다
python manage.py startapp <만들 app의 이름> # 여기서는 products
그 다음 settings.py
에 app 이름
추가
# products 디렉토리의 settings.py에 들어간다
INSTALLED_APPS = [
...
'products',
]
마지막으로 서버 실행(실패 시 오류 검증)
python manage.py
models.py
에서 ERD를 코드로 구현해야 한다.
구글링을 열심히 하고 저번에 다룬 스타벅스 ERD와 modeling을 참고하여
아래와 같이 models.py
를 만들었다.
(자세한 건 GitHub 코드 확인)
from django.db import models
# Create your models here.
class Menu(models.Model):
name = models.CharField(max_length=40)
class Meta:
db_table = 'menus'
class Category(models.Model):
name = models.CharField(max_length=40)
menu = models.ForeignKey('Menu', on_delete=models.CASCADE)
class Meta:
db_table = 'categories'
class Product(models.Model):
korean_name = models.CharField(max_length=100)
english_name = models.CharField(max_length=100)
description = models.TextField(max_length=300)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
allergy = models.ManyToManyField('Allergy', through='AllergyProduct')
class Meta:
db_table = 'products'
.
.
.
migration
은 아래와 같이 2단계를 밟아 진행하면 된다.python manage.py makemigrations
python manage.py migrate
mysql 명령어
를 이용하여 사용할 데이터베이스 westarbucks
를 찾아서 세부 테이블을 확인한다.
원하는 데이터베이스 확인
mysql> show databases;
+------------------------+
| Database |
+------------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| westarbucks |
+------------------------+
원하는 데이터베이스 사용
mysql> use westarbucks;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
아래와 같이 django를 통해 table이 생성되었을 것이다.
mysql> show tables;
+-----------------------+
| Tables_in_westarbucks |
+-----------------------+
| allergies |
| allergies_products |
| categories |
| django_content_type |
| django_migrations |
| django_session |
| images |
| menus |
| nutritions |
| products |
| sizes |
+-----------------------+
django
로 시작하는 것은 무시하자, 여기서는 다룰 내용이 아니다.
products
app에서 수정하고 싶은 Table(Menu
, Category
, ...)를 import
해야 한다.*
)을 import
하여 수고로움을 덜겠다.C.R.U.D
할 내용이 너무 많아 대표적인 한두 개의 코드만 남겨놓고 ...
로 생략하였다.# 원래는 C.R.U.D 할 Table만 해아 한다.
from products.models import Menu
# 편의상 아래와 같이
from products.models import *
Menu.objects.create(name='음료')
...
mysql> select * from menus;
+----+--------+
| id | name |
+----+--------+
| 1 | 음료 |
| 6 | 푸드 |
+----+--------+
이후에 Category
(mysql에서는 categories
)에 해당하는 걸 다 넣어 보자
Category.objects.create(name='콜드 브루', menu=drinks)
...
mysql> select * from categories;
+----+--------------------------------+---------+
| id | name | menu_id |
+----+--------------------------------+---------+
| 1 | 콜드 브루 | 1 |
| 2 | 브루드 커피 | 1 |
+----+--------------------------------+---------+
cold_brewed = Category.objects.get(id=1)
brewed_coffee = Category.objects.get(id=2)
...
Product.objects.create(korean_name='롤린 민트 초코 콜드 브루', english_name='Rollin Mint Choco Cold Brew', description='스타벅스의 콜드 브루와 은은한 민트 초코 베이스로 누구나 즐길 수 있는 여름 음료. 손목의 스냅을 춤을 추듯 가볍게 돌려 음료를 섞어서 빨대 없이 즐겨 보세요.', category=cold_brewed)
...
mysql> select * from products;
+----+---------------------------------------------+---------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+
| id | korean_name | english_name | description | category_id |
+----+---------------------------------------------+---------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+
| 1 | 롤린 민트 초코 콜드 브루 | Rollin Mint Choco Cold Brew | 스타벅스의 콜드 브루와 은은한 민트 초코 베이스로 누구나 즐길 수 있는 여름 음료. 손목의 스냅을 춤을 추듯 가볍게 돌려 음료를 섞어서 빨대 없이 즐겨 보세요. | 1 |
| 2 | 나이트로 바닐라 크림 | Nitro Vanilla Cream | 부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한번에 느껴보세요! | 1 |
+----+---------------------------------------------+---------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+
Product
같이 table의 개수가 많으면 보는 게 힘들다select *
를 쓰기 보다는mysql> select id, korean_name, category_id from products;
+----+---------------------------------------------+-------------+
| id | korean_name | category_id |
+----+---------------------------------------------+-------------+
| 1 | 롤린 민트 초코 콜드 브루 | 1 |
| 2 | 나이트로 바닐라 크림 | 1 |
+----+---------------------------------------------+-------------+
Allergy.objects.create(name='대두')
...
mysql> mysql> * from allergies;
+----+--------------+
| id | name |
+----+--------------+
| 1 | 대두 |
| 2 | 우유 |
+----+--------------+
AllergyProduct.objects.create(allergy_id=1, product_id=1)
AllergyProduct.objects.create(allergy_id=2, product_id=2)
...
mysql> select * from allergies_products;
+----+------------+------------+
| id | allergy_id | product_id |
+----+------------+------------+
| 1 | 2 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 2 |
+----+------------+------------+
Nutrition.objects.create(calories_kcal=210, saturated_fats_g=4.5, protein_g=6, sodium_mg=115, sugars_g=28, caffeine_mg=131, product=Product.objects.get(id=1))
mysql> select * from nutritions;
+----+---------------+------------------+-----------+-----------+----------+-------------+------------+---------+
| id | calories_kcal | saturated_fats_g | protein_g | sodium_mg | sugars_g | caffeine_mg | product_id | size_id |
+----+---------------+------------------+-----------+-----------+----------+-------------+------------+---------+
| 1 | 210.00 | 4.50 | 6.00 | 115.00 | 28.00 | 131.00 | 1 | 2 |
| 2 | 80.00 | 2.00 | 1.00 | 40.00 | 10.00 | 232.00 | 2 | 2 |
+----+---------------+------------------+-----------+-----------+----------+-------------+------------+---------+
URL 주소
는 Chrome의 개발자 도구
를 이용하여 구했다.
1. 단축키(Ctrl
/command
+ shift
+ i
또는 F12
) 또는 좌클릭 후 검사
눌러 개발자 도구 실행
2. 개발자 도구 좌측 상단에 마우스 클릭으로 해당 html
코드를 볼 수 있는 기능이 있다.(단축키: command
+ shift
+ c
)
3. 원하는 이미지를 클릭하면 html
문서에서 해당 이미지의 URL 주소
를 볼 수 있다.
Image.objects.create(image_url='https://image.istarbucks.co.kr/upload/store/skuimg/2022/04/[9200000003988]_20220406113215431.jpg', product_id=1)
...
mysql> select * from images;
+----+--------------------------------------------------------------------------------------------------+------------+
| id | image_url | product_id |
+----+--------------------------------------------------------------------------------------------------+------------+
| 1 | https://image.istarbucks.co.kr/upload/store/skuimg/2022/04/[9200000003988]_20220406113215431.jpg | 1 |
+----+--------------------------------------------------------------------------------------------------+------------+
Size.objects.create(name='Tall(톨)', size_ml=355, size_fluid_ounce=12)
mysql> mysql> * from sizes;
+----+-------------------+---------+------------------+
| id | name | size_ml | size_fluid_ounce |
+----+-------------------+---------+------------------+
| 1 | Tall(톨) | 355 | 12 |
+----+-------------------+---------+------------------+
C.R.U.D
를 하고 나서 다시 여러 테이블을 넣으려고 했는데 다음과 같은 에러가 발생하였다.You are trying to add a non-nullable field 'name' to allergy without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option: 2
ERD
와 Modeling
을 확실히 해놓고 migration
을 하자.Product
나 Nutrition
처럼 정보량이 테이블에 데이터를 담을 때 너무 힘들었다.😡크롤링
과정을 통해서 훨씬 쉽게 데이터를 가져올 수 있다는데... 지금은 CRUD 기초밖에 모르니 어쩔 수 없다.ipython
으로 이전 명령어를 불러올 수 있어 수고를 덜은 정도?