[Django] Django ORM Cookbook : 5

GreenBean·2021년 9월 30일
0

Django ORM Cookbook

목록 보기
5/8
post-thumbnail

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')


# SQL 질의문
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']>


# Lower를 사용
>>> 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']>


# annotate 메서드로 Lower를 적용한 열을 준비하고, 그 열을 기준으로 정렬
>>> 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' 인자에 이중 밑줄 기호(__)를 사용
    • 이중 밑줄 기호로 연결된 모델의 필드를 가리킬 수 있음
# SQL 질의문
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")
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글