Django C.R.U.D 1 - (3) QuerySet API 활용

minch·2021년 7월 18일
2

Django

목록 보기
7/16
post-thumbnail

QuerySet API 활용

Django Shell에서 QuerySet API를 이용하여 데이터를 생성(C), 조회(R), 수정(U), 삭제(D) 해보자.

먼저 django의 shell을 실행하고,

python manage.py shell

Shell에 models.py 안에 작성한 class를 불러온다.

>>> from products.models import Menu # 전부 불러오려면 import *

먼저 Menu에 해당하는 Data를 생성(Create)해보겠다.

>>> Menu.objects.create(name="음료") # create() method 사용
>>> Menu.objects.cretae(name="푸드")
>>> a3 = Menu(name="상품")
>>> a3.save() # save() method 까지 입력해야 해당 colunm이 생성됨
>>> a4 = Menu(name="카드")
>>> a4.save()

이런식으로 Shell에 입력하면, Database안의 해당하는 TABLE(여기서는 menus TABLE)에 column(name)들에 맞는 Data가 생성이 된다.

이를 mysql에서 확인할 수있는데, mysql에 해당하는 DB에 접근한다음,

menus TABLE의 모든 데이터를 불러오는 명령어를 입력하면,
column에 맞게 생성이 된 것을 확인 할 수 있다.

Django Shell에서 Data를 조회(Read)할 수 있는데,

>>> from products.models import Menu
>>> Menu.objects.all()
<QuerySet [<Menu: 음료>, <Menu: 푸드>, <Menu: 상품>, <Menu: 카드>]
>>> Menu.objects.get(name="음료")
<Menu: 음료>
>>> Menu.objects.filter(name="음료")
<QuerySet [<Menu: 음료>]>

all(), get(), filter() 등의 method를 이용하여 조회할 수 있다.

get() vs filter()

위에서 볼 수 있듯이, 두가지 method의 결과는 얼핏보면 같아 보인다.
하지만 이 둘에는 분명 차이점이 존재한다.

get()<Menu: 음료> 와 같이 attribute에 해당하는 instance(할당된 객체)를 반환하고, 만약 조건을 충족하는 여러 개가 있다면 error가 발생한다.

filter()<QuerySet [<Menu: 음료>]>와 같이 QuerySet 형태(list처럼 사용할 수 있지만, list는 아님)로 결과값을 반환한다. 이는 조건이 해당하는 객체가 여러개가 있다면 모두 반환 할 수 있다.

또, values()values_list() method를 이용하여 해당 데이터들의 자세한 값을 조회할 수 있는데,

>>> Menu.objects.get(name="음료").values()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Menu' object has no attribute 'values'
>>> Menu.objects.filter(name="음료").values()
<QuerySet [{'id': 1, 'name': '음료'}]>

values() method는 결과값이 QuerySet으로 반복 가능한 값일때만 사용할 수 있으며,
attribute의 이름을 key, 해당 data를 value
dict형태를 가진 QuerySet으로 반환한다.

>>> Menu.objects.get(name="음료").values_list()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Menu' object has no attribute 'values_list'
>>> Menu.objects.filter(name="음료").values_list()
<QuerySet [(1, '음료')]>

values_list() method도 마찬가지로 QuerySet일때만 사용할 수 있으며, dict형태가 아닌 tuple의 형태를 가진 QuerySet으로 반환한다는 차이가 있다.

Category 테이블 - CREATE, READ

그럼 다음으로, Category에 해당하는 Data를 생성해보자.

Category의 TABLE에는 Menu의 Primary Key(id)를 참조하는 Foreign Key를 가지고 있다. 즉, Many-to-one의 관계를 가진다는 것이다.

그렇기 때문에 이를 고려하여 Data를 생성해야하는데,

>>> a1 = Menu.objects.get(name="음료")
>>> Category.objects.create(name="콜드 브루 커피", menu=a1)

이런 식으로 해당하는 Menu를 미리 조회한 다음,
변수로 설정하여(a1 = Menu.objects.get(name="음료"))
Category Data를 생성할 때, menu attribute에 지정해 주면 된다.

create() 말고도, bulk_create() method를 사용하여 생성이 가능하다.

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

마찬가지로, mysql에서 DATA가 잘 생성되었는지 확인할 수 있다.

Category TABLE을 조회할 때도, Many-to-one의 관계를 고려해야 한다.

예를들어, Category 데이터 중 음료 Menu 를 참조하고 있는 데이터만 출력하고 싶다면,

>>> Category.objects.filter(menu_id=1)

OR

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

### 결과 ###
<QuerySet [<Category: 콜드 브루 커피>, <Category: 브루드 커피>]>

menu__name과 같이 Foreign Key로 연결된 TABLE의 데이터를 사용할 수도 있다!
이에 대한 자세한 내용들은 django 공식문서에 나와있으며,
이것을 바탕으로 하는 많은 연습이 필요하다.

UPDATE, DELETE

수정(Update), 삭제(Delete)하는 방법으로는

각각 update()delete() method를 이용하면 된다.

만약 Category에서 콜드 브루 커피콜드 블루 커피로 잘못 생성하였다면,
이를 해결하기 위해서

>>> Category.objects.filter(name="콜드 블루 커피").update(name="콜드 브루 커피")

위처럼 입력해주면 수정이 가능하다.

하지만 주의해야 할 점이 있는데,

update() method는 all() 이나 filter()와 같은
QuerySet을 이용한 것에서만 사용이 가능하다.

get()과 같은 인스턴스만을 반환하는 method에는 사용 불가,
그래서 save() method를 주로 이용
ex)

>>> category = Category.objects.get(name="콜드 블루 커피")

>>> category.name
`콜드 블루 커피`

>>> category.name = '콜드 브루 커피'
>>> categoy.save()

>>> category.name
'콜드 브루 커피'

delete() method는 반대로 어떠한 method에서도 사용이 가능하다.

ex)

>>> Category.objects.get(name="콜드 블루 커피").delete()

OR

>>> Category.objects.filter(name="콜드 블루 커피").delete()

전체 TABLE 결과

그래서 이렇게 다양한 method들을 이용하여 만든 전체 TABLE의 결과이다.

Product>

Nutrition>

Allergy & Allergy_Product>

Image>

0개의 댓글