🌈 프로그래밍/Django

[ Django ORM ] 문자열 숫자를 int로 캐스팅해서 정렬해보자.

반응형

 

보통 문자열 숫자를 정렬한다고 하면 ..

["60", "20", "0", "120", "0", "80"]

위와 같이 문자열로 이루어져있는 숫자들이 있다고 가정해보자.

별 다를 것 없이 정렬한다면 어떤 결과가 나올까?

실제 결과는 아래와 같다.

['0', '0', '120', '20', '60', '80']

0 다음에 120이 바로 나오게 된다. 왜냐하면 너무 당연하게도 앞문자열에 따라 120의 1이 20보다 빠르기 때문이다.

 

실제 나는 정렬하려고 하는 기준 데이터들은 다음과 같았다.

<MatchQuerySet [('BAD_WEATHER_20',), ('BAD_WEATHER_40',), ('BAD_WEATHER_60',), ('BAD_WEATHER_80',), ('BAD_WEATHER_60',), ('BAD_WEATHER_60',), ('BAD_WEATHER_60',), ('BAD_WEATHER_120',), ('BAD_WEATHER_40',)]>

해당 필드는 문자열이고 문자 + 숫자가 함께 저장되어있는 필드였다.

우선, BAD_WEATHER_ 이라는 문자열은 모두 공통이므로

from django.db.models.functions import Substr

Substr을 활용해서 값을 분리하여 뒤에 있는 숫자 문자열만 분리하도록 한다.

잘린 문자열 숫자들을 Int로 캐스팅한 뒤, 새로운 필드(num_from_string)을 만들어주도록 한다.

이 후 에는 위에서 만들어준 새로운 필드를 사용해서 정렬하도록 한다!

최종 ORM은 아래와 같았다.

from django.db.models import IntegerField
from django.db.models.functions import Cast, Substr

result_queryset = queryset.annotate(
    num_from_string=Cast(Substr("manager_weather", 13), IntegerField())
).order_by("num_from_string")


return result_queryset

 

- 정렬된 해당 문자열 필드에 대한 실제 값

print(result_queryset.values_list("manager_weather"))
<MatchQuerySet [('BAD_WEATHER_20',), ('BAD_WEATHER_40',), ('BAD_WEATHER_40',), ('BAD_WEATHER_60',), ('BAD_WEATHER_60',), ('BAD_WEATHER_60',), ('BAD_WEATHER_60',), ('BAD_WEATHER_80',), ('BAD_WEATHER_120',)]>

 

- 실행 결과

print(result_queryset.values_list("num_from_string"))
<MatchQuerySet [(20,), (40,), (40,), (60,), (60,), (60,), (60,), (80,), (120,)]>

 

반응형