C.R.U.D # 1 - Exercise

Jayson Hwang·2022년 5월 7일
0

Django Basics

목록 보기
4/14
post-thumbnail

초기 세팅을 끝낸 지난 "django_crud" 프로젝트에 이어서 진행!!
Git Repository 생성 & 로컬 프로젝트 연동 이후부터의 진행사항을 순서대로 서술합니다.



1.. 새로운 BRANCH 생성

  • 새로운 기능을 추가하기 위해서는 새로운 BRANCH에서 작업을 해야함

:: $ git checkout -b feature/product 명령어를 통해서, 새로운 Branch를 생성함과 동시에 그 Branch로 전환


2.. 새로운 App 생성

  • Model을 만들기전 상품관련된 기능을 만들기 위해 새로운 App을 만들어줌

:: $ python manage.py startapp product 명령어를 통해, 새로운 App을 생성

:::: 📌 새로운 App을 생성하게되면 항상 settings.pyINSTALLED_APPS에 해당 App을 추가!!!


3.. Models.py 코드 작성

  • $ cd product 명령어로 아까 생성한 product 폴더에 들어가면,
    Models.py 라는 파일이 존재하고 이 부분이 Application의 핵심!!!

3-1.. mysql 에서 직접 Table 생성 (간략한 과정 설명)

  • 어떻게 mysql에서 직접 Table을 생성하고 Data를 입력하는 지 확인하자!
    (아래 출력값들은 위 입력값에 대한 결과가 아니며, 그냥 이해를 돕기위해 형태만 보여주고자 추가함)
* mysql> show databases; # 존재하는 모든 databases를 확인하는 명령어

* mysql> create database (database name) character set utf8mb4 collate utf8mb4_general_ci;
	# 새로운 데이터 베이스 생성하는 명령
 
* mysql> use (database name);
    # 특정 이름을 갖은 database를 사용하는 명령어, 입력되면 "Database changed" 출력
  
* mysql> show tables; 
    # 존재하는 table을 보여주는 명령어 / Table이 비었다면, Empty set (0.01 sec) 출력

* mysql> CREATE TABLE products (
      ->		id INT NOT NULL AUTO_INCREMENT, 
      ->		name VARCHAR(50) NOT NULL,
      ->		price VARCHAR(100) NULL,
      ->		created_at TIMESTAMP NOT NULL DEFAULT NOW(),
      ->		PRIMARY KEY(id)
      ->);
  	# TABLE을 생성하는 명령어, 이름과 type, null여부에 대해 입력을 해주어야 알맞은 table이 생성된다.
  	# 제대로 입력하면, Query Ok, 0 rows affected (0.01 sec) 출력

* mysql> desc products; # 'desc' 명령어를 통해서 table에 값들이 제대로 입력이 되었는 지 확인 가능
					  #  아래와 같은 출력값을 보여준다.
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | bigint       | NO   | PRI | NULL    | auto_increment |
| name        | varchar(50)  | NO   |     | NULL    |                |
| price       | varchar(100) | NO   |     | NULL    |                |
| created_at  | datetime(6)  | NO   |     | NULL    |                |
| category_id | bigint       | NO   | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
  
* mysql> INSERT INTO products (name, price) VALUES ("Mac 16인치", "100000");
	# 데이터 값을 입력해주는 명령('products' 테이블에 value를 추가함)

* mysql> SELECT * FROM products;
  	# 특정 table(예제에서는 products) 안에 어떤 value값이 들어있는지 확인하는 명령
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | 콜드브루         |
|  2 ||
|  5 | 에스프레소        |
| 10 ||
| 11 ||
+----+-----------------+
5 rows in set (0.00 sec)
  
* mysql> drop database (database이름); # 특정 database를 삭제하는 명령

3-2.. "python" 코드만으로 "table" 생성 과정

  • /product/models.py에서 아래와 같이 코드를 작성하여 Table을 생성할 수 있다.(sql문 없이)

3-2-1.. models.py 작성

from django.db import models 

class Category(models.Model):
    name = models.CharField(max_length=20)
#   이름 = models.타입 (세부내용)
# 	Category 클래스를 생성
  
  
    class Meta:
        db_table = "categories"



class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.CharField(max_length=100)
    category = models.ForeignKey('Category', on_delete=models.CASCADE)
  	### ForeingKey 설정!!!!! 엄청 중요!!!
  	### ForeingKey 설정!!!!! 엄청 중요!!!
  	### ForeingKey 설정!!!!! 엄청 중요!!!
  	### ForeingKey 설정!!!!! 엄청 중요!!!
    created_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = "products"

::: 📌 ForeignKey on_delete의 종류 참고 (https://vallhalla-edition.tistory.com/60)

3-2-2.. makemigartions & migrate

::: makemigrations

$ git status ▶︎ $ git add . ▶︎ $ git status ▶︎ $ python manage.py makemigrations를 통해 product/migrations/0001_initial.py 라는 설계도를 생성

  • models.py에 작성한 python code를 database에 적용하기 위한 migration(설계도)를 만드는 과정


::: migrate

$ python manage.py migrate 명령어를 통해 모든 migration을 적용, Database에 table이 입력

  • makemigration 으로 생성한 Migration(설계도)를 database에 적용


4.. "shell" 에서 C.R.U.D

4-1.. Shell & import

  1. $ python manage.py shell 명령어로 Shell 활성화
  2. >>> product(App name).models import Menu, Category, etc.(class name)
    으로 작성한 모델 클래스를 import

4-2.. CREATE(**)

4-2-1.. create() Method

>>> Menu.objects.create(name="음료") # Menu라는 테이블에 "음료" 라는 column을 추가
#   (table name)

  
<<another example>>
  ---------------
>>> a1 = Menu.objects.get(name="음료")
>>> Category.objects.create(name="콜드 브루 커피", menu=a1)
>>> b1 = Category.objects.get(name="콜드 브루 커피")
>>> b1.menu.id
# b1의 menu의 id를 출력 // 출력값은 1 이 나옴

4-2-2.. save() Method

>>> a3 = Menu(name="상품")
>>> a3.save()
# Menu 테이블에 "상품" column 추가

4-2-3.. bulk_create() Method

Example 1)
  >>> a1 = Menu(name="음료")
  >>> a2 = Menu(name="푸드") 
  >>> Menu.objects.bulk_create([a1, a2])

Example 2)
  >>> a2 = Menu.objects.get(name="푸드")
  >>> Category.objects.bulk_create([
          Category(name="브레드", menu=a2), 
          Category(name="케이크", menu=a2)
     ])  

4-3.. READ(**)

4-3-1.. get() Method

>>> Menu.objects.get(name="음료")
>>> Menu.objects.get(id=1)

4-3-2.. filter() Method

>>> Category.objects.filter(menu_id=1)
>>> Category.objects.filter(menu__name="음료")

4-3-3.. _set 역참조 manager 사용

# 음료 메뉴를 참조하고 있는 모든 카테고리 출력 (QuerySet형태로)
>>> a1 = Menu.objects.get(name="음료")
>>> a1.category_set.all()
  
# 음료 메뉴를 참조하고 있는 모든 카테고리 개수 출력  
>>> a1 = Menu.objects.get(name="음료")
>>> a1.category_set.count()

4-4.. UPDATE(**)

....추후 추가예정....

4-5.. DELETE(**)

....추후 추가예정....



5.. Many To Many Relationship!!!!

#allergy
class Allergy(models.Model):
    name = models.CharField(max_length=45)
    

    class Meta:
        db_table = "Allergy"

  
#drinks
class Drinks(models.Model):
    categories = models.ForeignKey('Categories', on_delete=models.CASCADE)
    korean_name = models.CharField(max_length=45)
    english_name = models.CharField(max_length=45)
    allergy = models.ManyToManyField(Allergy, through='Allergy_drink')
    
    class Meta:
        db_table = "Drinks"

  
#allergy_drink
class Allergy_drink(models.Model):
    allergy = models.ForeignKey("Allergy", on_delete=models.CASCADE)
    drink = models.ForeignKey('Drinks', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = "Allergy_drink"

ManyToManyField 사용하는 이유?

  • 중간테이블(Allergy_drink)을 거치지 않고 Drinks를 통해서 바로 Allergy를 추가 가능 (Add)
In [6]: Allergy.objects.create(name='대두')
  
Out[6]: <Allergy: Allergy object (4)>

In [35]: a4 = Allergy.objects.get(id=4)

In [36]: c2 = Categories.objects.get(id=2)

In [37]: d3 = Drinks(korean_name='오곡라떼', categories=c2)

In [38]: d3.save()

In [39]: d3.allergies.add(a8) 
  
********************************중요***********************************
 d3.allergies.add(a1,a2,a3, ....) 여러값을 한번에 입력해주는 것도 가능하다!!!!!
**********************************************************************  
  • 만약 ManyToManyField가 아닌 ForeignKey로 연결하게되면,
    데이터를 추가할때 항상 중간테이블을 거쳐야함
In [3]: Allergy.objects.create(name='우유')
Out[3]: <Allergy: Allergy object (3)>

In [4]: c2 = Category.objects.get(id=2)

In [6]: Drink.objects.create(korean_name='오곡 라떼', category=c2)
Out[6]: <Drink: Drink object (3)>

In [7]: d3 = Drink.objects.get(id=3)

In [8]: a6 = Allergy.objects.get(id=6)

In [9]: AllergyDrink.objects.create(allergy=a6, drink=d3)
Out[9]: <AllergyDrink: AllergyDrink object (6)>  

더 자세한 내용: https://velog.io/@jxxwon/TIL.-36Many-To-Many-relationship%EC%9D%98-%EC%9E%A5%EC%A0%90

CRUD 링크

https://velog.io/@kim-hoontae/Django-QuerySet-API-%EB%A9%94%EC%86%8C%EB%93%9C
https://velog.io/@hyeseong-dev/djangoORMQuerySet-API-%EC%9E%90%EC%A3%BC%EC%93%B0%EB%8A%94-%EB%A9%94%EC%84%9C%EB%93%9C
https://kimdoky.github.io/django/2020/02/03/django-queryset-api/
https://phin09.tistory.com/57

profile
"Your goals, Minus your doubts, Equal your reality"

0개의 댓글