Django ORM
Django ORM Cookbook
쿼리셋 정렬
order_by
메서드로 쿼리셋을 정렬할 수 있음
- 기준 필드를 지정해 오름차순 혹은 내림차순으로 정렬 가능
- 기준 필드를 여러 개 지정할 수 있음
>>> User.objects.all().order_by('date_joined')
<QuerySet [<User: yash>, <User: John>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: Raghu>, <User: rishab>, <User: johny>, <User: paul>, <User: johny1>, <User: alien>]>
>>> User.objects.all().order_by('-date_joined')
<QuerySet [<User: alien>, <User: johny1>, <User: paul>, <User: johny>, <User: rishab>, <User: Raghu>, <User: Radha>, <User: Billy>, <User: Ritesh>, <User: sharukh>, <User: Ricky>, <User: John>, <User: yash>]>
>>> User.objects.all().order_by('date_joined', '-last_login')
SELECT "auth_user"."id", -- More fields -- , "auth_user"."date_joined"
FROM "auth_user"
ORDER BY "auth_user"."date_joined" ASC,
"auth_user"."last_login" DESC
대·소문자 구별하지 않고 정렬
order_by
메서드로 쿼리셋을 정렬할 때, 텍스트 필드를 기준으로 하면 알파벳의 대문자·소문자를 구분하여 정렬이 수행
- 대문자에 소문자보다 높은 우선순위가 부여
- 텍스트 필드에서 대문자·소문자를 구별하지 않고 정렬하려면 다음과 같이
Lower
를 사용하면 됨
annotate
메서드로 Lower
를 적용한 열을 준비하고, 그 열을 기준으로 정렬하는 방법도 가능
>>> User.objects.all().order_by('username').values_list('username', flat=True)
<QuerySet ['Billy', 'John', 'Radha', 'Raghu', 'Ricky', 'Ritesh', 'johny', 'johny1', 'paul', 'rishab', 'sharukh', 'sohan', 'yash']>
>>> from django.db.models.functions import Lower
>>> User.objects.all().order_by(Lower('username')).values_list('username', flat=True)
<QuerySet ['Billy', 'John', 'johny', 'johny1', 'paul', 'Radha', 'Raghu', 'Ricky', 'rishab', 'Ritesh', 'sharukh', 'sohan', 'yash']>
>>> User.objects.annotate(lower_name=Lower('username'))
.order_by('lower_name').values_list('username', flat=True)
여러 개의 필드를 기준으로 정렬
- 쿼리셋의
order_by
메서드에 여러 개의 정렬 기준 필드를 인자로 전달할 수 있음
- 그러면 여러 개의 필드를 기준으로 정렬이 수행됨
>>> from django.contrib.auth.models import User
>>> User.objects.all().order_by("is_active", "-last_login", "first_name")
<QuerySet [<User: Guido>, <User: shabda>, <User: Tim>]>
외래 키로 연결된 다른 표의 열을 기준으로 정렬
Hero
모델의 쿼리셋을 category 필드 순으로 정렬하되, category가 같은 항목은 (Hero
의) name 필드 순으로 정렬
>>> Hero.objects.all().order_by('category__name', 'name')
'category__name'
인자에 이중 밑줄 기호(__
)를 사용
- 이중 밑줄 기호로 연결된 모델의 필드를 가리킬 수 있음
SELECT "entities_hero"."id", "entities_hero"."name", -- more fields --
FROM "entities_hero"
INNER JOIN "entities_category" ON ("entities_hero"."category_id" = "entities_category"."id")
ORDER BY "entities_category"."name" ASC,
"entities_hero"."name" ASC
계산 필드 기준으로 정렬
Category
항목들을 각 Category
항목에 속한 Hero
항목의 개수에 따라 정렬하고 싶을 때
annotate
메서드로 계산 필드를 준비하여 기준으로 삼을 수 있음
>>> Category.objects.annotate(hero_count=Count("hero")
.order_by("-hero_count")