데이터베이스의 질의 인터페이스를 제공
디폴트 Manager 로서 ModelCls.objects 가 제공
# SELCT * FROM app_model;
ModelsCls.objects.all()
# SELCT * FROM app_model ORDER BY ID DESC LIMIT 10;
ModelsCls.objects.all().order_by('-id')[:10]
# INSERT INTO app_model (title) VALUES ("New Title");
ModelsCls.objects.create(title="New Title")
>>> qs = Post.objects.all()
>>> print(qs)
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>, <Post: 세번째 메세지>]>
>>>
>>> print(type(qs))
<class 'django.db.models.query.QuerySet'>
>>>
print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post"
>>>
>>> qs = Post.objects.all().order_by('id')
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" ORDER BY "instagram_post"."id" ASC
>>>
>>> qs
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>, <Post: 세번째 메세지>]>
>>>
## id 에 대해서 내림차순
>>> qs = Post.objects.all().order_by('-id')
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" ORDER BY "instagram_post"."id" DESC
>>> qs
<QuerySet [<Post: 세번째 메세지>, <Post: 두번째 메세지>, <Post: 첫번째 메세지>]>
>>>
>>> qs = Post.objects.all().order_by('-id')[:2]
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" ORDER BY "instagram_post"."id" DESC LIMIT 2
>>> qs
<QuerySet [<Post: 세번째 메세지>, <Post: 두번째 메세지>]>
>>>
>>> for post in qs:
... print(post.id, post.message, post.created_at)
... print("id: {id}, message: {message} {created_at}".format(**post.__dict__))
...
4 세번째 메세지 2022-01-12 11:07:37.336965+00:00
id: 4, message: 세번째 메세지 2022-01-12 11:07:37.336965+00:00
2 두번째 메세지 2022-01-11 10:56:29.125509+00:00
id: 2, message: 두번째 메세지 2022-01-11 10:56:29.125509+00:00
>>>
\
사용>>> qs = Post.objects.all().filter(message__startswith='첫번째')
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE "instagram_post"."message" LIKE 첫번째% ESCAPE '\'
>>> qs
<QuerySet [<Post: 첫번째 메세지>]>
>>>
>>> qs = Post.objects.all().filter(message__icontains='첫번째').order_by('-id')
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE "instagram_post"."message" LIKE %첫번째% ESCAPE '\' ORDER BY "instagram_post"."id" DESC
>>> qs
<QuerySet [<Post: 첫번째 메세지>]>
>>>
>>> qs = Post.objects.all()\
... .filter(message__icontains='첫번째')\
... .order_by('-id')
>>>
>>> qs
<QuerySet [<Post: 첫번째 메세지>]>
>>>
# filter : WHERE 문
>>> qs = Post.objects.all().filter(message__icontains='첫번째').order_by('-id')
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE "instagram_post"."message" LIKE %첫번째% ESCAPE '\' ORDER BY "instagram_post"."id" DESC
>>>
# exclude : WHERE NOT 문
>>> qs = Post.objects.all().exclude(message__icontains='첫번째').order_by('-id')
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE NOT ("instagram_post"."message" LIKE %첫번째% ESCAPE '\') ORDER BY "instagram_post"."id" DESC
>>> qs
<QuerySet [<Post: 세번째 메세지>, <Post: 두번째 메세지>]>
>>>
>>> qs = Post.objects.all()
>>> qs[1]
<Post: 두번째 메세지>
>>> qs[0]
<Post: 첫번째 메세지>
>>>
>>> qs[3]
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/django-with-react-study/venv/lib/python3.8/site-packages/django/db/models/query.py", line 318, in __getitem__
return qs._result_cache[0]
IndexError: list index out of range
>>> qs = Post.objects.all()
>>> qs.get(pk=1)
<Post: 첫번째 메세지>
>>> qs.get(pk=2)
<Post: 두번째 메세지>
>>>
>>> qs.get(pk=3)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/django-with-react-study/venv/lib/python3.8/site-packages/django/db/models/query.py", line 435, in get
raise self.model.DoesNotExist(
instagram.models.Post.DoesNotExist: Post matching query does not exist.
>>>
# lte: less than equal
>>> qs.get(id__lte=2)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/django-with-react-study/venv/lib/python3.8/site-packages/django/db/models/query.py", line 439, in get
raise self.model.MultipleObjectsReturned(
instagram.models.Post.MultipleObjectsReturned: get() returned more than one Post -- it returned 2!
>>>
>>> qs = Post.objects.all()
>>> qs.first()
<Post: 첫번째 메세지>
>>>
>>> qs.none()
<QuerySet []>
>>> qs.none().first()
>>>
>>> qs = Post.objects.all()
>>> qs.last()
<Post: 세번째 메세지>
>>>
>>> qs = Post.objects.all()
>>> qs = qs.exclude(id__gte=2, message__icontains="첫번째")
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE NOT ("instagram_post"."id" >= 2 AND "instagram_post"."message" LIKE %첫번째% ESCAPE '\')
>>> qs
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>, <Post: 세번째 메세지>]>
>>>
>>>
>>> qs = Post.objects.all()
>>> qs = qs.filter(id__gte=2, message__icontains="첫번째")
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE ("instagram_post"."id" >= 2 AND "instagram_post"."message" LIKE %첫번째% ESCAPE '\')
>>> qs
<QuerySet []>
>>>
>>> from django.db.models import Q
>>> qs = Post.objects.all()
>>> qs = qs.filter(Q(id__gte=2) | Q(message__icontains="첫번째"))
>>> qs.query
<django.db.models.sql.query.Query object at 0x7f68dbe7ab80>
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE ("instagram_post"."id" >= 2 OR "instagram_post"."message" LIKE %첫번째% ESCAPE '\')
>>> qs
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>, <Post: 세번째 메세지>]>
>>>
>>> qs = Post.objects.all()
>>> cond = Q(id__gte=2) | Q(message__icontains='첫번째')
>>> qs = qs.filter(cond)
>>> print(qs.query)
SELECT "instagram_post"."id", "instagram_post"."message", "instagram_post"."photo", "instagram_post"."is_public", "instagram_post"."created_at", "instagram_post"."updated_at" FROM "instagram_post" WHERE ("instagram_post"."id" >= 2 OR "instagram_post"."message" LIKE %첫번째% ESCAPE '\')
>>> qs
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>, <Post: 세번째 메세지>]>
>>>
주의) 데이터베이스 타입에 따라서 생성되는 SQL이 다릅니다.
1) 필드명__lt = 조건값
1) 필드명__startswith = 조건값
정렬 조건을 추가하지 않으면 일관된 순서를 보장받을 수 없음
하지만 가급적 단일 필드로 하는 것이 성능에 이익
시간숙/역순 정렬이 필요할 경우, ID 필드를 활용
class Post(models.Model):
class Meta:
ordering = ['-id']
모든 Queryset에 order_by(...)에 지정
>>> Post.objects.all().order_by('created_at')
SELECT "instagram_post"."id",
"instagram_post"."message",
"instagram_post"."photo",
"instagram_post"."is_public",
"instagram_post"."created_at",
"instagram_post"."updated_at"
FROM "instagram_post"
ORDER BY "instagram_post"."created_at" ASC
LIMIT 21
Execution time: 0.000249s [Database: default]
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>, <Post: 세번째 메세지>]>
>>>
객체[start:stop:step]
- offset : start
- LIMIT : stop - start
- STEP은 Query에 대응되지 않음.
>>> Post.objects.all()[:2]
SELECT "instagram_post"."id",
"instagram_post"."message",
"instagram_post"."photo",
"instagram_post"."is_public",
"instagram_post"."created_at",
"instagram_post"."updated_at"
FROM "instagram_post"
ORDER BY "instagram_post"."id" DESC
LIMIT 2
Execution time: 0.000153s [Database: default]
<QuerySet [<Post: 세번째 메세지>, <Post: 두번째 메세지>]>
>>> Post.objects.all()[-2:]
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/django-with-react-study/venv/lib/python3.8/site-packages/django/db/models/query.py", line 294, in __getitem__
assert ((not isinstance(k, slice) and (k >= 0)) or
AssertionError: Negative indexing is not supported.
>>>
>>> Post.objects.all().order_by('id')[:2]
SELECT "instagram_post"."id",
"instagram_post"."message",
"instagram_post"."photo",
"instagram_post"."is_public",
"instagram_post"."created_at",
"instagram_post"."updated_at"
FROM "instagram_post"
ORDER BY "instagram_post"."id" ASC
LIMIT 2
Execution time: 0.000208s [Database: default]
<QuerySet [<Post: 첫번째 메세지>, <Post: 두번째 메세지>]>
>>>
2
(STEP) 을 처리함.>>> Post.objects.all()[1:3]
SELECT "instagram_post"."id",
"instagram_post"."message",
"instagram_post"."photo",
"instagram_post"."is_public",
"instagram_post"."created_at",
"instagram_post"."updated_at"
FROM "instagram_post"
ORDER BY "instagram_post"."id" DESC
LIMIT 2
OFFSET 1
Execution time: 0.000204s [Database: default]
<QuerySet [<Post: 두번째 메세지>, <Post: 첫번째 메세지>]>
>>>
>>> Post.objects.all()[1:3:1]
SELECT "instagram_post"."id",
"instagram_post"."message",
"instagram_post"."photo",
"instagram_post"."is_public",
"instagram_post"."created_at",
"instagram_post"."updated_at"
FROM "instagram_post"
ORDER BY "instagram_post"."id" DESC
LIMIT 2
OFFSET 1
Execution time: 0.000120s [Database: default]
[<Post: 두번째 메세지>, <Post: 첫번째 메세지>]
>>>