세션 진행: 지훈님
Create
Read
Update
Delete
장고 = 2세대 프레임워크
python manage.py shell에서 CRUD를 할 수 있다.
>>> Products.objects.create(name = '사과')
<Products: Products object (1)>
>>> Products.objects.all()
<QuerySet [<Products: Products object (1)>]>
>>> a = Products(name = '바나나')
>>> a.save()
>>> a
<Products: Products object (2)> # 아까 값을 하나 입력했기 때문에 2번째로 배정을 받은 것이다.
>>> Products.objects.all()
<QuerySet [<Products: Products object (1)>, <Products: Products object (2)>]> # 테이블에 데이터 두줄을 의미한다.
>>> Products.objects.all()
<QuerySet [<Products: Products object (1)>, <Products: Products object (2)>]>
위의 예제를 그대로 가져와서
Products.objects.get()을 하면 테이블에는 데이터가 두개가 있기 때문에 에러가 난다.
>>> Products.objects.get(name = '원재연')
<Products: Products object (1)>
>>> Products.objects.get()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/pro16/miniconda3/envs/test/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/pro16/miniconda3/envs/test/lib/python3.9/site-packages/django/db/models/query.py", line 433, in get
raise self.model.MultipleObjectsReturned(
products.models.Products.MultipleObjectsReturned: get() returned more than one Products -- it returned 2! # 하나만 가져와야하는데 테이블 안에 데이터가 두개나 들어가 있다!
여기서 알아야 할 점은 클래스명.objects.all()은 출력값에 Queryset이 붙어 나오지만 클래스명.objects.get()은 클래스명 형식으로 나온다.
>>> Products.objects.filter(name='원재연')
<QuerySet [<Products: Products object (1)>]>
Queryset으로 감싸져 있지만 안에는 클래스명으로 되어 있다.
>>> Products.objects.values()
<QuerySet [{'id': 1, 'name': '원재연', 'created_at': datetime.datetime(2021, 3, 26, 11, 29, 41, 541024, tzinfo=<UTC>), 'updated_at': datetime.datetime(2021, 3, 26, 11, 29, 41, 541081, tzinfo=<UTC>)}, {'id': 2, 'name': '원재투', 'created_at': datetime.datetime(2021, 3, 26, 11, 30, 48, 519259, tzinfo=<UTC>), 'updated_at': datetime.datetime(2021, 3, 26, 11, 30, 48, 519297, tzinfo=<UTC>)}]>
Queryset으로 감싸져 있고 딕셔너리로 한번 더 감싸져 있다.
원하는 데이터를 색출 해내는 것이 실력과 직결이 되어 있기 때문에 차이를 잘 알아야 한다.
>>> a = Products.objects.get(id =1) # a 변수를 클래스로 감싸져 있는 get으로 read한다
>>> a
<Products: Products object (1)> # a를 출력해보니 역시 클래스로 감싸져 있다.
>>> a.name # a를 출력해보니 내가 원하는 값이 나온다.
'원재연'
>>> b = Products.objects.filter(id =2) # Queryset으로 감싸져 있는 filter로 b라는 변수를 선언한다.
>>> b # b를 출력해보니 역시나 Queryset으로 묶여있다.
<QuerySet [<Products: Products object (2)>]>
>>> b.name # b.name을 출력해보니 Queryset으로 감싸져있어 에러가 난다.
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'QuerySet' object has no attribute 'name'
>>> b[0] # 하지만 필터는 Queryset안에 또 리스트로 감싸져있어 리스트로 인식이 된다.
<Products: Products object (2)>
>>> b[0].name # 인덱스를 사용하여 name을 출력하니 출력이 잘된다. 하지만 잘 쓰지 않는다.
'원재투'
>>> a.name # 원재연을 원재쓰리로 바꾸고 싶을 때
'원재연'
>>> a.name = '원재쓰리' # 이렇게 선언만 해보겠다.
>>> a
<Products: Products object (1)>
>>> a.name # 잘 적용된건가 싶지만
'원재쓰리'
>>> a = Products.objects.get(id=1) # 다시 read를 해오면
>>> a.name # 바뀌지 않은 것을 볼 수 있다.
'원재연'
>>> a.name = '원재쓰리' # 그래서 값을 바꾸고 꼭 save()를 해야 한다.
>>> a.save()
>>> a.name
'원재쓰리'
>>> a = Products.objects.get(id=1)
>>> a.name # 다시 read를 해도 바뀌지 않은 것을 볼 수 있다.
'원재쓰리'
클래스명.objects.filter().update(변경값)으로 업데이트 가능하다.
>>> Products.objects.filter(id = 2).update(name = '투재연') # id 2번에 있는 항목을 투재연으로 바꾸고 싶다.
1 # True라는 뜻
>>> b = Products.objects.get(id = 2) # id 2번 값을 불러온다.
>>> b.name # 출력해보면 투재연으로 바뀐것을 확인 할 수 있다.
'투재연'
클래스명.objects.get(위치).delete()로 할 수 있다.
>>> Products.objects.get(id = 2).delete() # id 2번에 있는 값을 지우고 싶다.
(1, {'products.Products': 1}) # 잘 지웠으니 테이블 안에 남은 데이터는 이것이다.
>>> b = Products.objects.get(id = 2) # id 2번에 있는 데이터를 불러보지만 존재하지 않는다.
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/pro16/miniconda3/envs/test/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/pro16/miniconda3/envs/test/lib/python3.9/site-packages/django/db/models/query.py", line 429, in get
raise self.model.DoesNotExist(
products.models.Products.DoesNotExist: Products matching query does not exist.