ORM (Object-Relational-Mapping)
: 객체 지향 프로그래밍 언어를 사용하여 호환되지 않는 유형의 시스템 간에 데이터를 변환하는 기술
ORM의 역할

QuerySet API
: ORM에서 데이터를 검색, 필터링, 정렬 및 그룹화 하는 데 사용하는 도구
-> API를 사용하여 SQL이 아닌 Python 코드로 데이터를 처리



Query: 데이터베이스에 특정한 데이터를 보여 달라는 요청
- "쿼리문을 작성한다." => 원하는 데이터를 얻기 위해 데이터베이스에 요청을 보낼 코드를 작성한다.
- 파이썬으로 작성한 코드가 ORM에 의해 SQL로 변환되어 데이터베이스에 전달되며, 데이터베이스의 응답 데이터를 ORM이 QuerySet이라는 자료 형태로 변환하여 우리에게 전달
QuerySet: 데이터베이스에게서 전달 받은 객체 목록(데이터 모음); 순회가 가능한 데이터로써 1개 이상의 데이터를 불러와 사용할 수 있음
- Django ORM을 통해 만들어진 자료형
- 단, 데이터베이스가 단일한 객체를 반환할 때는 QuerySet이 아닌 모델(Class)의 인스턴스로 반환됨
QuerySet API는 python의 모델 클래스와 인스턴스를 활용해 DB에 데이터를 저장, 조회, 수정, 삭제하는 것

Django Shell
: Django 환경 안에서 실행되는 python shell (입력하는 QuerySet API 구문이 Django 프로젝트에 영향을 미침)
Django shell 실행






대표적인 조회 메서드

all()

filter()

get()

*특징: 객체를 찾을 수 없으면 DoesNotExist 예외를 발생시키고, 둘 이상의 객체를 찾으면 MultiObjectsReturned 예외를 발생시킴
=> 위와 같은 특징을 가지고 있기 때문에 primary key와 같이 고유성(uniqueness)을 보장하는 조회에서 사용해야 함



In [3]: article = Article()
In [4]: article.title = 'first'
In [5]: article.content = 'django!'
In [6]: article.save()
In [7]: article
Out[7]: <Article: Article object (1)>
In [8]: Article.objects.all()
Out[8]: <QuerySet [<Article: Article object (1)>]>
In [9]: article.created_at
Out[9]: datetime.datetime(2024, 3, 25, 5, 39, 38, 544561, tzinfo=datetime.timezone.utc)
In [10]: article = Article(title='second', content='django!!')
In [11]: article.title
Out[11]: 'second'
In [12]: article.content
Out[12]: 'django!!'
In [13]: article
Out[13]: <Article: Article object (None)>
In [14]: article.save()
In [15]: article.pk
Out[15]: 2
In [16]: article.id
Out[16]: 2
In [17]: Article.objects.create(title='third', content='django!!!')
Out[17]: <Article: Article object (3)>
In [18]: Article.objects.all()
Out[18]: <QuerySet [<Article: Article object (1)>, <Article: Article object (2)>, <Article: Article object (3)>]>
In [19]: articles = Article.objects.all()
In [20]: for article in articles:
...: print(article)
...:
Article object (1)
Article object (2)
Article object (3)
In [21]: for article in articles:
...: print(article.title)
...:
first
second
third
In [22]: Article.objects.filter(content='django!')
Out[22]: <QuerySet [<Article: Article object (1)>]>
In [23]: Article.objects.filter(content='django!!')
Out[23]: <QuerySet [<Article: Article object (2)>]>
In [24]: Article.objects.filter(title='first')
Out[24]: <QuerySet [<Article: Article object (1)>]>
In [25]: Article.objects.get(pk=1)
Out[25]: <Article: Article object (1)>
In [26]: article = Article.objects.get(id=1)
In [27]: article.title
Out[27]: 'first'
In [28]: article.content
Out[28]: 'django!'
In [29]: Article.objects.get(pk=100)
---------------------------------------------------------------------------
DoesNotExist Traceback (most recent call last)
Cell In[29], line 1
----> 1 Article.objects.get(pk=100)
File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\manager.py:87, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs)
85 @wraps(method)
86 def manager_method(self, *args, **kwargs):
---> 87 return getattr(self.get_queryset(), name)(*args, **kwargs)
File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\query.py:637, in QuerySet.get(self, *args, **kwargs)
635 return clone._result_cache[0]
636 if not num:
--> 637 raise self.model.DoesNotExist(
638 "%s matching query does not exist." % self.model._meta.object_name
639 )
640 raise self.model.MultipleObjectsReturned(
641 "get() returned more than one %s -- it returned %s!"
642 % (
(...)
645 )
646 )
DoesNotExist: Article matching query does not exist.
In [30]: Article.objects.filter(content='django!')
Out[30]: <QuerySet [<Article: Article object (1)>]>
In [31]: Article.objects.get(title='first')
Out[31]: <Article: Article object (1)>
In [32]: article = Article.objects.get(pk=3)
In [33]: article.pk
Out[33]: 3
In [34]: article.title = 'ssafy'
In [35]: article.save()
In [36]: article.title
Out[36]: 'ssafy'
In [37]: article = Article.objects.get(pk=2)
In [38]: article.pk
Out[38]: 2
In [39]: article.delete()
Out[39]: (1, {'articles.Article': 1})
In [40]: Article.objects.get(pk=2)
---------------------------------------------------------------------------
DoesNotExist Traceback (most recent call last)
Cell In[40], line 1
----> 1 Article.objects.get(pk=2)
File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\manager.py:87, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs)
85 @wraps(method)
86 def manager_method(self, *args, **kwargs):
---> 87 return getattr(self.get_queryset(), name)(*args, **kwargs)
File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\query.py:637, in QuerySet.get(self, *args, **kwargs)
635 return clone._result_cache[0]
636 if not num:
--> 637 raise self.model.DoesNotExist(
638 "%s matching query does not exist." % self.model._meta.object_name
639 )
640 raise self.model.MultipleObjectsReturned(
641 "get() returned more than one %s -- it returned %s!"
642 % (
(...)
645 )
646 )
DoesNotExist: Article matching query does not exist.
In [41]: Article.objects.create(title='aaa', content='aaa')
Out[41]: <Article: Article object (4)>
In [42]: article = Article.objects.get(pk=4)
In [43]: article.pk
Out[43]: 4
In [44]: article.delete()
Out[44]: (1, {'articles.Article': 1})
In [45]: Article.objects.create(title='bbb', content='bbb')
Out[45]: <Article: Article object (5)>
In [46]: Article.objects.filter(content__endswith='!')
Out[46]: <QuerySet [<Article: Article object (1)>, <Article: Article object (3)>]>
In [47]: exit()
(venv)