Django ORM
Django ORM Cookbook
SQL 질의문 확인
- 장고 ORM이 실행하는 실제 SQL 질의문 확인
>>> queryset = Event.objects.filter(years_ago__gt=5)
>>> str(queryset.query)
SELECT "events_event"."id", "events_event"."epic_id","events_event"."details",
"events_event"."years_ago" FROM "events_event"
WHERE "events_event"."years_ago" > 5
OR 연산
- OR 연산으로 여러 조건 중 하나라도 만족하는 행을 구해야 하는 경우
queryset_1 | queryset_2
filter(Q(<condition_1>)|Q(<condition_2>))
>>> queryset = User.objects.filter(first_name__startswith='R') | User.objects.filter(last_name__startswith='D')
>>> queryset
<QuerySet [<User: Ricky>, <User: Ritesh>, <User: Radha>, <User: Raghu>, <User: rishab>]>
>>> str(queryset.query)
SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
"auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
"auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
WHERE ("auth_user"."first_name"::text LIKE R% OR "auth_user"."last_name"::text LIKE D%)
>>> from django.db.models import Q
>>> qs = User.objects.filter(Q(first_name__startswith='R')|Q(last_name__startswith='D'))
>>> str(qs.query)
SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
"auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
"auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
WHERE ("auth_user"."first_name"::text LIKE R% OR "auth_user"."last_name"::text LIKE D%)
AND 연산
- AND 연산으로 여러 조건을 모두 만족하는 행을 구해야 하는 경우
queryset_1 & queryset_2
filter(<condition_1>, <condition_2>)
filter(Q(<condition_1>) & Q(<condition_2>))
>>> queryset_1 = User.objects.filter(first_name__startswith='R') & User.objects.filter(last_name__startswith='D')
>>> queryset_2 = User.objects.filter(first_name__startswith='R', last_name__startswith='D')
>>> from django.db.models import Q
>>> queryset_3 = User.objects.filter(Q(first_name__startswith='R') & Q(last_name__startswith='D'))
>>> str(queryset_1.query)
SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
"auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
"auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
WHERE ("auth_user"."first_name"::text LIKE R% AND "auth_user"."last_name"::text LIKE D%)
>>> str(queryset_1.query) == str(queryset_2.query) == str(queryset_3.query)
True
NOT 연산
- 조건을 만족하지 않는 행을 구해야 하는 경우
exclude(<condition>)
filter(~Q(<condition>))
SELECT id, username, first_name, last_name, email FROM auth_user WHERE NOT id < 5;
>>> queryset = User.objects.exclude(id__lt=5)
>>> queryset
<QuerySet [<User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> from django.db.models import Q
>>> queryset = User.objects.filter(~Q(id__lt=5))
>>> queryst
<QuerySet [<User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
UNION 연산
- 장고 ORM에서
union
메서드를 이용해 쿼리셋을 합할 수 있음
- 합하려는 쿼리셋의 모델이 서로 다른 경우, 각 쿼리셋에 포함된 필드와 데이터 유형이 서로 맞아야 함
- union 메서드는 합하려는 쿼리셋의 필드와 데이터 유형이 서로 일치할 때만 실행할 수 있음
values_list()
를 이용해 공통된 필드만 가져온 뒤 union을 수행할 수 있음
>>> q1 = User.objects.filter(id__gte=5)
>>> q1
<QuerySet [<User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> q2 = User.objects.filter(id__lte=9)
>>> q2
<QuerySet [<User: yash>, <User: John>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>]>
>>> q1.union(q2)
<QuerySet [<User: yash>, <User: John>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> q2.union(q1)
<QuerySet [<User: yash>, <User: John>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> q3 = EventVillain.objects.all()
>>> q3
<QuerySet [<EventVillain: EventVillain object (1)>]>
>>> q1.union(q3)
django.db.utils.OperationalError: SELECTs to the left and right of UNION do not have the same number of result columns
Hero.objects.all().values_list("name", "gender")
.union(Villain.objects.all().values_list("name", "gender"))
필요한 열만 골라서 조회
- 필드가 전부 다 필요하지 않을 때, 필요한 열만을 데이터베이스에서 읽어오는 방법
- 쿼리셋의
values()
메서드와 values_list()
메서드
only
메서드
SELECT "auth_user"."first_name", "auth_user"."last_name"
FROM "auth_user" WHERE "auth_user"."first_name"::text LIKE R%
>>> User.objects.filter(first_name__startswith='R')
.values('first_name', 'last_name')
<QuerySet [{'first_name': 'Ricky', 'last_name': 'Dayal'}, {'first_name': 'Ritesh', 'last_name': 'Deshmukh'}, {'first_name': 'Radha', 'last_name': 'George'}, {'first_name': 'Raghu', 'last_name': 'Khan'}, {'first_name': 'Rishabh', 'last_name': 'Deol'}]
>> queryset = User.objects.filter(first_name__startswith='R')
.only("first_name", "last_name")
>>> str(queryset.query)
SELECT "auth_user"."id", "auth_user"."first_name", "auth_user"."last_name"
FROM "auth_user" WHERE "auth_user"."first_name"::text LIKE R%