스타벅스 음료 모델로 연습하는 Queryset

.·2020년 6월 6일
1

Coding

목록 보기
31/33

1 . 실습을 위해 자료를 클론해오기.

스타벅스모델링 및 데이터베이스 클론해오기

git clone 해온 경로를 찾아 들어가서 sqlite3 파일이 있는 곳에서 아래와 같이 실행한다.

sqlite3 db.sqlite3 을 치고 들어가서 .tables 를 입력하면 아래와 같이 데이터베이스에 여러 테이블 들이 생성되어 있는 것을 확인할 수 있다.

SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .tables
allergies            django_content_type  images
allergies_drinks     django_migrations    menus
categories           django_session       nutritions
descriptions         drinks               sizes

카테고리에서 생성되어 있는 모든 카테고리를 확인한 뒤,

sqlite> select * from categories;
1|콜드 브루 커피|1
2|브루드 커피|1
3|에스프레소|1
4|프라푸치노|1
5|블렌디드|1
6|스타벅스 피지오|1
7|티(티바나)|1
8|기타 제조 음료|1
9|스타벅스 주스(병음료)|1
10|베이커리|2
11|케이크|2
12|샌드위치 & 샐러드|2
13|따뜻한 푸드|2
14|과일 & 요거트|2
15|스낵 & 미니 디저트|2
16|아이스크림|2

실습을 위해 카테고리를 모두 지운다.
일단 뭔가 해보기 전에 스타벅스 모델의 구조를 알아야 한다.

2. 스타벅스 product/models.py

from django.db import models

class Menu(models.Model):
    name = models.CharField(max_length=10)

    class Meta:
        db_table = 'menus'

class Category(models.Model):
    name = models.CharField(max_length=50)
    menu = models.ForeignKey('Menu', on_delete=models.SET_NULL, null=True)

    class Meta:
        db_table = 'categories'

class Drink(models.Model):
    name          = models.CharField(max_length=50)
    menu          = models.ForeignKey('Menu', on_delete = models.SET_NULL, null=True)
    category      = models.ForeignKey('Category', on_delete = models.SET_NULL, null=True)
    nutrition     = models.OneToOneField('Nutrition', on_delete = models.SET_NULL, null=True)
    allergy_drink = models.ManyToManyField('Allergy', through='AllergyDrink')

    class Meta:
        db_table = 'drinks'

product 앱 내의 모델은 위의 코드보다 더 길지만 일단 지금 실습에 필요한 정보는 저 정도면 충분하다.

이미지를 보면 알 수 있듯이 MENU 에는 '음료','푸드','상품','카드','메뉴 이야기' 로 크게 다섯가지 메뉴 카테고리로 나뉘어져 있다.
maincategory 라 부르면 적합하다.

그리고 각각의 메뉴 카테고리들은 '콜드 브루', '브루드 커피', '베이커리', '머그' 등의 다양한 카테고리들을 가지고 있으며 각각의 카테고리들은 상위 메뉴 카테고리를 foreignkey 로 물고 있다.
이는 subcategory 라 부르면 이해가 쉽다.

즉 카테고리 '콜드 브루' 는 메뉴 '음료' 를 foreignkey 로 물고 있다.

그리고 음료를 보면 음료 이름과 더불어 메뉴와 카테고리를 foreignkey 로 물고 있다.
콜드 브루 커피를 예로 들자면, 1번 메뉴의 1번 콜드 브루 카테고리를 물고 있는 음료 로 이해하면 된다.

이제 데이터베이스에 categories 부분을 모두 지운 것을 확인 후 shell 에 가서 queryset 연습을 하러 가자.

명령어는 manage.py 가 있는 파일 경로에서 아래와 같이 실행시킨다.

./manage.py shell

3-1. Category.objects.all()

그리고 해당하는 앱의 모델 테이블을 확인하거나 변경하고자 할 때는 import 를 해와야 한다.

>>> from product.models import Category, Drink
Category.objects.all()
2020-06-04 15:20:23,027 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet []>

위의 날짜는 일부러 나오게 만든 설정이니 신경쓰지 않아도 되고 저기 쿼리셋이 아까 db 에서 지웠기 때문에 비어 있음을 확인할 수 있다.

그럼 이제 음료의 카테고리들을 몇개 만들어 보자. 아까 위에서도 확인했지만 다시 한번 보면 카테고리들은 name 이 있고, menu를 foreignkey 로 물고 있다. 그 뜻은 음료의 카테고리를 생성하려면 카테고리의 name과 menu_id 가 필요하다는 말이 된다. foreignkey 로 물고 있는 대상은 자동으로 'underbar id' 가 생성된다.

그럼 메뉴는 어떻게 db 에 저장되어 있고 각각의 primary key 는 어떻게 되어 있는지 확인해 보면 다음과 같다.

sqlite> select * from menus;
1|음료
2|푸드
3|상품
4|카드

menu '음료' 의 id 는 1번이다.

그럼 이제 정말로 menu '음료' 의 카테고리를 만들어 보자.

>>> Category.objects.create(name="콜드 브루 커피", menu_id=1)
2020-06-04 15:29:01,984 DEBUG (0.002) INSERT INTO "categories" ("name", "menu_id") VALUES ('콜드 브루 커피', 1); args=['콜드 브루 커피', 1]
<Category: Category object (17)>
>>> Category.objects.create(name="브루드 커피", menu_id=1)
2020-06-04 15:30:50,718 DEBUG (0.001) INSERT INTO "categories" ("name", "menu_id") VALUES ('브루드 커피', 1); args=['브루드 커피', 1]
<Category: Category object (18)>
>>> Category.objects.create(name="에스프레소", menu_id=1)
2020-06-04 15:31:07,899 DEBUG (0.001) INSERT INTO "categories" ("name", "menu_id") VALUES ('에스프레소', 1); args=['에스프레소', 1]
<Category: Category object (19)>
>>> Category.objects.create(name="프라푸치노", menu_id=1)
2020-06-04 15:31:22,931 DEBUG (0.001) INSERT INTO "categories" ("name", "menu_id") VALUES ('프라푸치노', 1); args=['프라푸치노', 1]
<Category: Category object (20)>

그런데 왜 object (17) 부터 시작할까?
아까 데이터베이스를 확인해 봤듯이 카테고리가 16까지 있었는데 지웠었다. db 에서는 1번부터 시작하는 것이 아니라 지워진 다음 key 부터 시작한다고 한다.

카테고리의 전체 객체를 불러와 본다.

>>> Category.objects.all()
2020-06-04 15:38:40,692 DEBUG (0.001) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet [<Category: Category object (17)>, 
<Category: Category object (18)>, 
<Category: Category object (19)>, 
<Category: Category object (20)>]>

카테고리에 있는 모든 정보들이 들어오는데 (객체를 쿼리셋에 담는 느낌) 결과물이 쿼리셋이라는 list 형식으로 object 객체를 가지고 온다. 하지만 객체로 나와서 무슨 내용인지 보이지 않는다.

이렇게 전체 조회 하는 것이 objects.all() 말고 더 있다.

3-2. Category.objects.values()

그것은 objects.vaules() 이다.
객체 object 들을 언패킹 하는 것이다. 모든 value 를 펼치고 category 의 id 와 name, menu 에 물린 foreignkey 인 menu_id 들이 다 펼쳐진다.

카테고리의 밸류를 불러와 본다.

>>> Category.objects.values()
2020-06-04 15:41:59,698 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet [{'id': 17, 'name': '콜드 브루 커피', 'menu_id': 1}, 
{'id': 18, 'name': '브루드 커피', 'menu_id': 1}, 
{'id': 19, 'name': '에스프레소', 'menu_id': 1}, 
{'id': 20, 'name': '프라푸치노', 'menu_id': 1}]>

기억해야 할 점은 위의 Category.objects.values() 가 가져온 형태는 list 안의 dictionary 형태라는 것이다. dictionary 형태.

카테고리의 all(), 그리고 카테고리의 values() 를 임의의 변수에 할당해 준다.

>>> category_all = Category.objects.all()
>>> category_values = Category.objects.values()
>>> category_all
2020-06-04 15:47:18,252 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet [<Category: Category object (17)>, 
<Category: Category object (18)>, 
<Category: Category object (19)>, 
<Category: Category object (20)>]>
>>> category_values
2020-06-04 15:47:27,174 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet [{'id': 17, 'name': '콜드 브루 커피', 'menu_id': 1}, 
{'id': 18, 'name': '브루드 커피', 'menu_id': 1}, 
{'id': 19, 'name': '에스프레소', 'menu_id': 1}, 
{'id': 20, 'name': '프라푸치노', 'menu_id': 1}]>

QuerySet 은 배열 List 형태를 갖추고 있다. list의 n 번째 를 가져오려면 list[ n ] 으로 해당하는 인덱스를 가져올 수 있다.

>>> category_all[0]
2020-06-04 15:48:42,843 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 1; args=()
<Category: Category object (17)>
>>> category_values[0]
2020-06-04 15:50:41,467 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 1; args=()
{'id': 17, 'name': '콜드 브루 커피', 'menu_id': 1}

category class 의 속성인 name 에 접근하려면 어떻게 해야 할까?

>>> category_all[0].name
2020-06-04 15:53:22,107 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 1; args=()
'콜드 브루 커피'

3-3. Category.objects.all() 의 속성에 접근해 보기

category_all[0] 을 변수에 담고 각각의 속성에 접근해 보자.

>>> cold = category_all[0]
2020-06-04 16:05:36,270 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 1; args=()
>>> cold.name
'콜드 브루 커피'
>>> cold.menu
2020-06-04 16:06:15,950 DEBUG (0.000) SELECT "menus"."id", "menus"."name" FROM "menus" WHERE "menus"."id" = 1 LIMIT 21; args=(1,)
<Menu: Menu object (1)>
>>> cold.menu_id
1

그런데 아까 해봤던 category_values() 의 경우에는 각각의 속성에 접근하는 방법이 다르다.

>>> category_values
2020-06-04 15:47:27,174 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet [{'id': 17, 'name': '콜드 브루 커피', 'menu_id': 1}, 
{'id': 18, 'name': '브루드 커피', 'menu_id': 1}, 
{'id': 19, 'name': '에스프레소', 'menu_id': 1}, 
{'id': 20, 'name': '프라푸치노', 'menu_id': 1}]>

3-4. Category.objects.values() 의 속성에 접근해 보기

category_values() 도 임의의 변수에 담아 각각의 속성에 접근해 보자.

>>> category_values[0]
2020-06-04 15:50:41,467 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 1; args=()
{'id': 17, 'name': '콜드 브루 커피', 'menu_id': 1}
>>> cold2 = category_values[0]
2020-06-04 16:07:37,975 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 1; args=()
>>> cold2.name
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'name'

위에서 보듯 .name 으로는 접근이 되지 않는다. 이유는 가져온 형태가 dictionary 이기 때문이다. 그렇다면 딕셔너리의 밸류를 가져오는 방식으로 접근해야 한다.

아래와 같다.

>>> cold2
{'id': 17, 'name': '콜드 브루 커피', 'menu_id': 1}
>>> cold2['name']
'콜드 브루 커피'
>>> cold2['menu_id']
1

3-5. QuerySet 반복문 돌리기

category_all 은 객체를 쿼리셋 에 담은 list 리스트와 같으므로 for loops 반복문을 돌릴 수가 있다.

>>> category_all
2020-06-04 15:47:18,252 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" LIMIT 21; args=()
<QuerySet [<Category: Category object (17)>, 
<Category: Category object (18)>, 
<Category: Category object (19)>, 
<Category: Category object (20)>]>

반복문을 돌린 모습은 다음과 같다.

>>> for category in category_all:
...     print(category.name)
...
콜드 브루 커피
브루드 커피
에스프레소
프라푸치노

그리고 DB 에서 확인해본 음료의 카테고리는 다음과 같다. 여기에는 베이커리 카테고리 나 머그, 실물카드 등의 여러 카테고리를 넣어도 상관이 없다. menu 의 id 를 다르게 넣어주면 되니까 말이다.

sqlite> select * from categories;
17|콜드 브루 커피|1
18|브루드 커피|1
19|에스프레소|1
20|프라푸치노|1

4-1. Drink.objects.create()

dbsqlite3 에서 음료 drink 데이터 베이스를 확인해 보도록 하자.

sqlite> select * from drinks;
1|나이트로 바닐라 크림|1|1|1
2|제주 비자림 콜드 브루|1|1|2
3|코코넛 화이트 콜드 브루|1|1|3
4|나이트로 쇼콜라 클라우드|1|1|4
5|콜드 브루 몰트|1|1|5
6|아이스 커피|2|1|6
7|오늘의 커피|2|1|7
8|에스프레소 콘 파나|3|1|8

마찬가지로 실습을 위해 모두 지워 주자.

>>> from product.models import Drink
>>> Drink.objects.all()
2020-06-04 16:23:18,365 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" LIMIT 21; args=()
<QuerySet []>

쿼리셋이 비어 있고 이제 여기에 음료를 넣어 보도록 하자.

>>> Drink.objects.create(name='나이트로 바닐라 크림',menu_id=1,category_id=17)
2020-06-04 16:28:00,825 DEBUG (0.002) INSERT INTO "drinks" ("name", "menu_id", "category_id", "nutrition_id") VALUES ('나이트로 바닐라 크림', 1, 17, NULL); args=['나이트로 바닐라 크림', 1, 17, None]
<Drink: Drink object (9)>

'나이트로 바닐라 크림' drink 의 menu_id 는 '음료' 인 1번, category_id 는 '콜드 브루' 인 17번 이다.

하지만 좀 전에 '콜드 브루' 카테고리를 만들어서 카테고리가 17번 이라는 것을 기억하고 있을 뿐이지 카테고리가 한도 없이 많아지면 매번 입력해 넣을 때 위처럼 카테고리 id 를 일일이 외워서 넣을 수 없다.

4-2. Drink.objects.create(category_id=가 수만백개라면 어떻게?)

일일이 카테고리 id 를 외워서 넣을 수 없다.
자 그럼 어떻게 해 볼까.
Drink.objects.create(name='나이트로 바닐라 크림',menu_id=1,category_id=17)

아까 생성했던 음료의 각 카테고리마다 고유의 id (primary-key) 가 자동 생성되는 것을 기억하고 있어야 한다.

카테고리에서 name 이 '콜드 브루 커피' 인 것을 가져왔으면 한다.
get 을 사용한다.

>>> c = Category.objects.get(name='콜드 브루 커피')
2020-06-04 16:37:38,663 DEBUG (0.001) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" WHERE "categories"."name" = '콜드 브루 커피' LIMIT 21; args=('콜드 브루 커피',)
>>> c
<Category: Category object (17)>
>>> c.id
17

그럼 다시 음료를 생성해 넣어 보자.

drink table 에 '제주 비자림 콜드 브루' 를 넣는데 menu_id 는 1번인데 category 의 id 는 기억이 잘 안난다. 하지만 콜드 브루 카테고리 의 음료라는 사실을 알고 있으므로 위에 c 에 기록한 id 변수를 대입 시켜줘 보자.

>>> Drink.objects.create(name='제주 비자림 콜드 브루', menu_id=1, category_id=c.id)
2020-06-04 16:46:06,125 DEBUG (0.002) INSERT INTO "drinks" ("name", "menu_id", "category_id", "nutrition_id") VALUES ('제주 비자림 콜드 브루', 1, 17, NULL); args=['제주 비자림 콜드 브루', 1, 17, None]
<Drink: Drink object (10)>

category_id=c.id 간단해 보이지만 매우 중요한 아이디어 이다.
그럼 이제 drink 에 넣은 객체들을 불러와 보자.

  • all 로 불러오기
>>> Drink.objects.all()
2020-06-04 16:46:32,353 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" LIMIT 21; args=()
<QuerySet [<Drink: Drink object (9)>, <Drink: Drink object (10)>]>
  • values() 로 불러오기
>>> Drink.objects.values()
2020-06-04 16:58:20,724 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" LIMIT 21; args=()
<QuerySet [{'id': 9, 'name': '나이트로 바닐라 크림', 'menu_id': 1, 'category_id': 17, 'nutrition_id': None}, 
{'id': 10, 'name': '제주 비자림 콜드 브루', 'menu_id': 1, 'category_id': 17, 'nutrition_id': None}]>

>>> drink_values = Drink.objects.values()
>>> drink_values[0]['name']
2020-06-04 17:00:04,147 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" LIMIT 1; args=()
'나이트로 바닐라 크림'

DB 에서 확인한 음료테이블의 요소들은 아래와 같다.

sqlite> select * from drinks;
9|나이트로 바닐라 크림|17|1|
10|제주 비자림 콜드 브루|17|1|

5. 베이커리 카테고리 만들어 넣어 보기

아까 처음에 menu='음료'에 해당하는 카테고리들을 넣었다면 이번엔 menu='푸드' 에 해당하는 카테고리인 '베이커리' 를 넣어 보자.

sqlite> select * from menus;
1|음료
2|푸드
3|상품
4|카드

'category' 에서 바라보는 '푸드' 의 menu_id 는 2 임을 알 수 있다.

>>> Category.objects.create(name='베이커리', menu_id=2)
2020-06-04 17:02:04,024 DEBUG (0.002) INSERT INTO "categories" ("name", "menu_id") VALUES ('베이커리', 2); args=['베이커리', 2]
<Category: Category object (21)>

DB에서 확인해보면 아래와 같다.

sqlite> select * from categories;
17|콜드 브루 커피|1
18|브루드 커피|1
19|에스프레소|1
20|프라푸치노|1
21|베이커리|2

카테고리명 뒤에 나오는 숫자는 foreignkey로 물고 있는 menu_id 라는 것을 눈치챌 수 있다.

6. 음료에 '에스프레소 콘 파나' 넣어보기

'에스프레소 콘 파나' 의 category_id 가 무엇인지 알지 못한다.
이름에서 일단 카테고리가 '에스프레소' 라는 것은 유추해 볼 수 있다.

shell 에 'from product.models import Menu, Category, Drink' 를 먼저 불러 오도록 한다.

6-1. 카테고리 중 '에스프레소' 의 id 를 얻어오기

Category.objects.get(name='에스프레소').id

19번이라고 뚝딱 나온다.
이제 이걸 가지고 변수에 대입을 해보고 요리조리 뜯어 볼 것이기 때문에 임의의 변수에 할당해준다.
category_id 에 주도록 하겠다.

>>> category_id = Category.objects.get(name='에스프레소').id
2020-06-04 17:10:05,177 DEBUG (0.000) SELECT "categories"."id", "categories"."name", "categories"."menu_id" FROM "categories" WHERE "categories"."name" = '에스프레소' LIMIT 21; args=('에스프레소',)
>>> category_id
19

6-2. 메뉴 중 '음료' 의 id 를 얻어오기

아까 넣어서 1번인 줄은 알지만 극단적으로 메뉴의 종류가 아주 많다고 하면 이것도 연습해 보도록 하자.

>>> menu_id = Menu.objects.get(name='음료').id
2020-06-04 17:22:34,943 DEBUG (0.000) SELECT "menus"."id", "menus"."name" FROM "menus" WHERE "menus"."name" = '음료' LIMIT 21; args=('음료',)
>>> menu_id
1

6-3. Drink.objects.create(name='에스프레소 콘 파나', menu_id=?, category_id=?)

자 이제 Drink 테이블에 '에스프레소 콘 파나' 를 넣고자 하는데 foreignkey 로 엮인 menu_id 와 category_id 가 필요하다.

최초에 menu_id 1번, category_id 19번에 넣은 걸 알지만 django 는 그 사실을 전혀 알지 못한다.
그래서 6-1 과 6-2 처럼 객체의 id 에 .(dot) 으로 접근해서 임의의 변수 menu_id, category_id 에 넣었다.

>>> Drink.objects.create(name='에스프레소 콘 파나', menu_id=menu_id, category_id=category_id)
2020-06-04 17:24:59,839 DEBUG (0.002) INSERT INTO "drinks" ("name", "menu_id", "category_id", "nutrition_id") VALUES ('에스프레소 콘 파나', 1, 19, NULL); args=['에스프레소 콘 파나', 1, 19, None]
<Drink: Drink object (11)>

>>> Drink.objects.values()
2020-06-04 17:25:16,227 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" LIMIT 21; args=()
<QuerySet [{'id': 9, 'name': '나이트로 바닐라 크림', 'menu_id': 1, 'category_id': 17, 'nutrition_id': None}, 
{'id': 10, 'name': '제주 비자림 콜드 브루', 'menu_id': 1, 'category_id': 17, 'nutrition_id': None}, 
{'id': 11, 'name': '에스프레소  파나', 'menu_id': 1, 'category_id': 19, 'nutrition_id': None}]>

- Drink.objects.create(name='에스프레소 콘 파나', menu_id=menu_id, category_id=category_id) 에서 앞에 있는 menu, category_id 는 키값이고, 뒤에 있는 menu, category_id 는 지정해둔 변수라는 것을 알아두자.

sqlite> select * from drinks;
9|나이트로 바닐라 크림|17|1|
10|제주 비자림 콜드 브루|17|1|
11|에스프레소 콘 파나|19|1|

7. objects.get 과 objects.filter 의 차이를 이해하기

get 과 filter 의 공통점은 특정 조건을 단다 라는 점에서는 비슷하다.

7-1. get

drink 객체에서 id 가 11번 인 것을 들고 온다.

>>> Drink.objects.get(id=11)
2020-06-04 17:38:17,190 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" WHERE "drinks"."id" = 11 LIMIT 21; args=(11,)
<Drink: Drink object (11)>

여기에서 알 수 있듯 get 은 하나 만 가져 올 수 있고 객체 자체를 가져온다.
그리고 객체 에서 . (dot) 을 통해 각 속성에 접근할 수 있다.

>>> Drink.objects.get(id=11).name
2020-06-04 17:38:23,603 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" WHERE "drinks"."id" = 11 LIMIT 21; args=(11,)
'에스프레소 콘 파나'

이제 get 자리에 get 을 지우고 대신 'filter' 메소드를 써 준다면 어떻게 될까?

7-2. filter

카테고리아이디가 17 인 '콜드 브루' 인 음료 객체를 불러온다.

>>> Drink.objects.filter(category_id=17)
2020-06-04 17:43:07,731 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" WHERE "drinks"."category_id" = 17 LIMIT 21; args=(17,)
<QuerySet [<Drink: Drink object (9)>, <Drink: Drink object (10)>]>

get 과 달리 filter 는 쿼리셋에 담겨 여러 개를 가져 올 수 있다.

>>> Drink.objects.filter(category_id=17).values()
2020-06-04 17:43:47,138 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" WHERE "drinks"."category_id" = 17 LIMIT 21; args=(17,)
<QuerySet [{'id': 9, 'name': '나이트로 바닐라 크림', 'menu_id': 1, 'category_id': 17, 'nutrition_id': None}, 
{'id': 10, 'name': '제주 비자림 콜드 브루', 'menu_id': 1, 'category_id': 17, 'nutrition_id': None}]>

filter 를 하면 쿼리셋에 접근하기 때문에 그 대상의 [ ? ] 번째.속성 에 접근할 수가 있다.

>>> Drink.objects.filter(category_id=17)[1].name
2020-06-04 17:47:59,383 DEBUG (0.000) SELECT "drinks"."id", "drinks"."name", "drinks"."menu_id", "drinks"."category_id", "drinks"."nutrition_id" FROM "drinks" WHERE "drinks"."category_id" = 17 LIMIT 1 OFFSET 1; args=(17,)
'제주 비자림 콜드 브루'
profile
.

0개의 댓글