Django 6.1 프리뷰: 신규 기능 및 아키텍처 변화 총정리
Django 6.1 프리뷰: 신규 기능 및 아키텍처 변화 총정리

Django 6.1 프리뷰 버전의 주요 기능 변화와 그 배경에 대해 한눈에 살펴보기 쉽게 정리했습니다. 각 기능이 “왜 도입되었고, 어디에 어울릴지”에 대한 개인적인 추측과 함께 살펴보겠습니다.
1. 모델 필드 fetch mode
Django 모델 필드의 지연 로딩 동작을 fetch mode로 설정할 수 있게 됐습니다. 즉, 아직 가져오지 않은 필드에 접근했을 때 Django가 데이터를 어떻게 가져올지 제어할 수 있습니다.
Django는 세 가지 fetch mode를 제공합니다.
FETCH_ONE은 기본값이며, 현재 인스턴스에 필요한 필드만 가져옵니다. 기존 Django 동작과 같습니다.FETCH_PEERS는 같은QuerySet에서 나온 모든 인스턴스에 대해 필요한 필드를 함께 가져옵니다.prefetch_related()를 나중에 자동으로 수행하는 느낌에 가깝습니다. 대부분의 “N+1 쿼리 문제”를 별도 prefetch 필드 목록 관리 없이 두 번의 쿼리로 줄일 수 있습니다.RAISE는 의도치 않은 필드 로딩이 발생하면FieldFetchBlocked예외를 발생시킵니다. 성능이 중요한 코드 구간에서 예상치 못한 쿼리를 막는 용도로 유용합니다.
새 메서드 QuerySet.fetch_mode()로 QuerySet에서 가져온 모델 인스턴스의 fetch mode를 지정할 수 있습니다.
from django.db import models
books = Book.objects.fetch_mode(models.FETCH_PEERS)
for book in books:
print(book.author.name)
위 코드는 반복문 안에서 각 book.author에 접근하지만, FETCH_PEERS 덕분에 전체적으로 두 번의 쿼리만 수행됩니다.
- 모든 책을 가져옵니다.
- 관련된 저자를 가져옵니다.
아마도 내가 보기엔
이 기능은 Django ORM의 오랜 현실 문제인 “실수로 발생하는 N+1 쿼리”를 완화하기 위해 도입된 것이 아닐까 추측해 봅니다. select_related()와 prefetch_related()가 강력하긴 하지만, 개발자가 미리 예측하여 적용해야 한다는 어려움이 있습니다. 실제 서비스에서는 serializer, template, admin, API response 등이 생성되는 과정에서 뒤늦게 필드 접근이 발생하는 경우가 많기 때문입니다.
FETCH_PEERS는 목록 화면, API 리스트 응답, admin change list, CSV export처럼 동일한 QuerySet의 여러 객체를 순회하며 관련 필드에 접근하는 시나리오에 어울릴 듯합니다. 성능 최적화는 필요하지만 모든 관계를 미리 일일이 관리하기 부담스러운 코드에 적절한 대안이 될 수 있어 보입니다.
RAISE는 이보다 더 엄격한 통제가 필요한 곳에 적합할 것 같습니다. 예를 들어 결제, 리포트 생성, 대량 배치, 핵심 API 경로(hot path) 등 쿼리 횟수를 명확하게 예측해야 하는 구간에서 의도치 않은 DB 조회를 막아주는 안전장치(guardrail) 역할을 기대할 수 있습니다. 또한, 테스트 코드에서 “특정 구간 내 추가 쿼리 발생 금지” 정책을 강제하는 용도로도 유용하게 쓰일 것 같습니다.
2. ForeignKey.on_delete의 데이터베이스 레벨 삭제 옵션
ForeignKey.on_delete에서 데이터베이스 레벨 삭제 옵션을 지원합니다.
새 옵션은 다음과 같습니다.
DB_CASCADEDB_SET_NULLDB_SET_DEFAULT
이 옵션들은 삭제 로직을 Django 파이썬 레벨이 아니라 SQL의 ON DELETE 절을 사용해 데이터베이스에서 직접 처리합니다. 기존의 파이썬 레벨 CASCADE, SET_NULL, SET_DEFAULT보다 효율적일 수 있습니다. Django가 삭제 대상 객체를 모두 로드할 필요가 없기 때문입니다.
다만 중요한 차이가 있습니다. DB_CASCADE는 Django의 pre_delete, post_delete signal을 발생시키지 않습니다. 삭제 signal에 의존하는 코드가 있다면 무작정 바꾸면 안 됩니다.
아마도 내가 보기엔
대량 삭제 시의 성능을 개선하고 데이터베이스 자체 제약 조건과의 정합성을 높이기 위해 추가된 기능으로 보입니다. 기존 Django의 on_delete=CASCADE는 ORM이 관계를 추적하며 객체를 메모리에 로드해 처리하는 방식에 가깝습니다. 이 방식은 시그널이나 커스텀 로직 작동에는 유리하지만, 대용량 데이터 처리 시 성능 저하나 메모리 부하를 유발할 수 있습니다.
DB_CASCADE 계열은 삭제 시 별도의 애플리케이션 레벨 로직이 필요 없이, 데이터베이스가 즉시 처리해도 무방한 관계에 적절할 것으로 생각됩니다. 로그, 임시 데이터, 종속적인 부속 테이블이나 중간 테이블처럼 부모 객체 삭제에 따라 자식 객체도 함께 완전히 제거되어야 하는 구조에 유용할 듯합니다.
반면, 삭제 시그널(pre_delete, post_delete)을 통해 파일 삭제, 외부 API 호출, 변경 이력(audit log) 생성, 검색 인덱스 갱신 등을 수행하는 구조에는 어울리지 않을 수 있습니다. 따라서 “빠른 DB 네이티브 삭제”가 요구되는 영역에 한해 이 옵션을 검토하고, 이벤트 발생이 중요한 곳에서는 기존 파이썬 레벨 옵션을 유지하는 것이 비교적 안전할 것 같습니다.
3. Mailers
새로운 MAILERS 설정이 추가됐습니다. 여러 이메일 백엔드를 각기 다른 옵션으로 설정할 수 있습니다. 구조는 기존의 CACHES, DATABASES, STORAGES, TASKS와 비슷합니다.
MAILERS = {
"default": {
"BACKEND": "django.core.mail.backends.smtp.EmailBackend",
"OPTIONS": {"host": "smtp.example.com", "use_tls": True},
},
"marketing": {
"BACKEND": "example.third.party.EmailBackend",
"OPTIONS": {"region": "africa-1"},
},
}
이메일 전송 함수에서 새 using 인자를 사용해 특정 mailer를 선택할 수 있습니다. 또는 mail.mailers[alias]로 이메일 백엔드 인스턴스를 얻을 수도 있습니다.
MAILERS는 아직 기존 프로젝트에서 기본 활성화되지는 않습니다. Django 7.0에서 EMAIL_BACKEND와 관련 EMAIL_* 설정을 대체할 예정입니다. Django 6.1에서는 기존 이메일 설정도 계속 동작하지만, deprecation warning이 발생합니다. 따라서 Django 7.0 전까지는 MAILERS로 옮겨가는 준비를 하는 것이 좋습니다.
아마도 내가 보기엔
현대의 이메일 발송 요구사항이 단일 SMTP 서버를 사용하는 방식에서 다변화되었기 때문에 도입된 변화가 아닐까 싶습니다. 최근의 웹 서비스들은 인증 메일, 비밀번호 재설정, 트랜잭션 알림, 마케팅 메일, 관리자 알림 등을 서로 다른 서비스 제공업체(Provider)나 설정을 통해 발송하곤 합니다.
기존의 EMAIL_BACKEND, EMAIL_HOST 등의 전역 설정은 단순한 구조에는 편리하지만, 복수의 메일 백엔드를 구성하기에는 다소 한계가 있었습니다. MAILERS 도입은 DATABASES나 CACHES처럼 별칭(alias) 기반으로 여러 백엔드를 유연하게 선택할 수 있도록 정리한 구조로 보입니다.
SaaS와 같은 복합 서비스 환경에서 꽤 유용하게 쓰일 수 있을 것 같습니다. 예를 들어 default는 회원가입이나 비밀번호 재설정용으로, marketing은 대량 뉴스레터용으로, alerts는 장애 모니터링 알림용으로 각각 분리하여 구성할 수 있습니다. 메일 발송량이나 실패 정책, 인증 키, 리전(region) 등을 별도로 관리해야 하는 규모 있는 프로젝트에 적절한 해결책이 될 수 있을 것으로 보입입니다.
4. django.contrib.admin 개선
- admin 로그인 뷰가 이미 인증된 사용자를 항상 admin index로 보내는 대신, 가능한 경우
nextURL로 리다이렉트합니다. - admin의
FilteredSelectMultiple위젯이 이제<optgroup>을 사용해 named group choices를 보존합니다. ModelAdmin.list_select_related가 기본값인False일 때, change list는 더 이상 모든 외래 키 필드를 select하지 않습니다. 대신ModelAdmin.list_display에 지정된 외래 키 필드만 선택합니다. 외래 키가 많은 모델에서는 admin 목록 성능이 좋아질 수 있습니다.delete_confirmation_max_display옵션이 추가됐습니다. admin 삭제 확인 페이지에서 표시할 객체 수를 제한할 수 있습니다. 기본값은None으로, 제한이 없습니다.- admin change form의 접근성도 개선됐습니다. 폼 필드는 라벨 옆이 아니라 아래에 표시되고, help text는 라벨 뒤와 입력 필드 앞에 표시됩니다. validation error도 help text 뒤, 입력 필드 앞에 표시됩니다. 체크박스는 기존 레이아웃을 유지합니다.
list_display는 관련 모델의 boolean 필드에도 boolean icon을 사용합니다.action()데코레이터에location인자가 추가됐습니다. admin action을 change list에서만 쓸지, change form에서도 쓸지 제어할 수 있습니다.action()데코레이터에description_plural인자도 추가됐습니다. change list에서 action 설명을 복수형에 맞게 별도로 지정할 수 있습니다.
아마도 내가 보기엔
어드민(admin)은 Django의 아주 강력한 무기이지만, 기존 UI의 구조적 한계와 대규모 데이터를 다룰 때의 성능 병목 현상이 늘 아쉬운 점으로 지적받아 왔습니다. 이번 개선사항들은 성능 향상, 웹 접근성 제고, 그리고 관리 액션(action)의 사용성 극대화라는 관점에서 도입된 것으로 보입니다.
list_select_related 동작 방식의 변경은 외래 키 관계가 복잡하게 얽힌 모델들의 목록 조회 성능을 보완하기 위한 노력의 일환으로 생각됩니다. 외래 키 데이터를 무조건 전부 로딩하는 기존 방식은 소형 프로젝트에선 편리할지 모르나, 대규모 실서비스 도메인 모델에서는 무분별한 쿼리를 유발하기 쉽습니다. 따라서 외래 키가 많이 포함된 주문, 콘텐츠, 로그 관련 어드민 페이지 성능 개선에 유용하게 작용할 것 같습니다.
delete_confirmation_max_display 옵션은 대규모 일괄 삭제 작업을 수행할 때 화면이 지나치게 길어지거나 브라우저 렌더링 성능이 저하되는 현상을 방지해 줄 것으로 보입니다. 수천 개의 데이터를 일시에 지우는 백오피스 환경에 적절한 안전 장치가 될 수 있습니다.
접근성 향상 조치는 공공 서비스나 대형 엔터프라이즈 내부 툴에서 꽤 환영받을 만한 부분인 것 같습니다. 폼 필드의 배치 수정과 에러 메시지의 노출 위치 개선 등을 통해 화면 낭독기 지원이나 폼 작성 시의 가시성이 한층 개선될 것으로 보입니다.
action(location=...) 지원은 목록에서의 다중 선택 액션뿐 아니라, 개별 객체의 상세 페이지(change form) 내에서 즉시 관리 작업을 실행할 수 있는 유연함을 확보하기 위한 조치로 생각됩니다. 개별 주문 환불이나 회원 제재 등 건별 집중 처리가 잦은 백오피스 운영 환경에 잘 맞을 것 같습니다.
5. django.contrib.auth 개선
- PBKDF2 password hasher의 기본 반복 횟수가
1,200,000에서1,500,000으로 증가했습니다. - migration으로 모델 이름을 변경할 때
Permission.name과Permission.codename도 함께 변경됩니다. - 새
Permission.user_perm_str속성이 추가됐습니다.User.has_perm()에 넘기기 적합한 permission 문자열을 반환합니다.
아마도 내가 보기엔
PBKDF2의 기본 반복 횟수(iteration) 증가는 CPU/GPU 등 하드웨어 성능의 발전 속도에 맞춰 보안 최솟값을 꾸준히 높여온 Django의 전형적인 정책 기조를 반영한 조치로 보입니다. 무차별 대입 공격(Brute-force)의 비용을 상대적으로 증대시키기 위함이며, 일반적인 서비스라면 기본 설정을 그대로 따르는 것이 합리적일 것 같습니다.
모델 변경 마이그레이션 시의 권한명(permission name/codename) 자동 동기화 기능은, 장기적으로 유지보수하는 프로젝트에서 모델명을 변경할 때 권한 정보가 구형 명칭으로 남는 부조화를 해소하려는 의도로 보입니다. 도메인 용어가 바뀌어 리팩토링할 때 어드민 권한명이 어긋나 고생하는 일을 덜어줄 것으로 기대됩니다.
Permission.user_perm_str 속성은 권한 문자열을 하드코딩하거나 수동으로 조립할 때 생길 수 있는 오타 등의 실수를 미연에 방지하는 용도로 쓰일 듯합니다. 커스텀 어드민 제작이나 API 권한 검사 시, "app_label.codename" 구조의 문자열을 안전하게 조회하는 데 도움을 줄 것 같습니다.
6. django.contrib.gis 개선
- SpatiaLite에서
isemptylookup과IsEmpty()데이터베이스 함수를 지원합니다. - PostGIS와 SpatiaLite에서 geometry의 dimension 수로 필터링할 수 있는
num_dimensionslookup과NumDimensions()함수가 추가됐습니다. OpenLayersWidget이 OpenLayers7.2.2에서10.9.0기반으로 업데이트됐습니다.
아마도 내가 보기엔
그간 GIS 기능이 PostGIS를 중심으로 발전해온 경향이 있으나, 로컬 테스트나 소규모 경량 배포 환경에서는 SQLite 기반의 SpatiaLite도 꽤 중요하게 쓰이곤 합니다. SpatiaLite에 대한 추가적인 함수 지원은 로컬과 실서비스 환경 간의 격차를 줄이고 이식성을 제고하려는 방향성에서 비롯된 것이 아닐까 생각합니다.
num_dimensions 조회 기능은 2D와 3D 지형 정보가 혼재되어 있는 공간 데이터베이스 환경에서 데이터 필터링 시 유용하게 활용될 수 있을 것 같습니다. 도시 계획, 부동산 정보, 물류 배송 등 위치 정합성과 공간 정보의 차원 구분이 철저해야 하는 비즈니스에 적합해 보입니다.
OpenLayers 위젯 버전 업데이트는 관리자 페이지용 공간 지도 컴포넌트의 현대화 작업의 일환으로 풀이됩니다. 구형 웹 브라우저 대응이나 보안 패치 면에서 혜택을 볼 수 있으며, 어드민에서 지도를 보며 데이터를 직접 편집하는 어플리케이션에 도움이 될 듯합니다.
7. django.contrib.postgres 개선
inspectdb가HStoreField를 introspect할 수 있게 됐습니다. 조건은psycopg 3.2+가 설치되어 있고,django.contrib.postgres가INSTALLED_APPS에 포함되어 있어야 합니다.ExclusionConstraint가 Hash index type을 지원합니다.
아마도 내가 보기엔
inspectdb 명령어의 HStoreField 인식 기능은 이미 존재하던 PostgreSQL 데이터베이스 스키마를 기반으로 Django 프로젝트의 모델을 역설계(reverse engineering)해야 하는 개발 시나리오를 지원하기 위한 조치로 생각됩니다. 기존 레거시 시스템이나 외부 DB에서 이관 작업을 수행할 때 생성되는 코드가 한층 정교해질 것으로 기대됩니다.
ExclusionConstraint에 대한 Hash index 지원은 PostgreSQL 고유의 강력한 정합성 제어 기능을 Django ORM 수준에서 보다 자연스럽게 구현하기 위한 시도로 해석됩니다. 회의실 예약 겹침 방지, 일정 중복 검사 등 고급 제약 조건을 DB 자체에서 무결하게 관리해야 하는 시스템에 유용할 것으로 보입니다.
8. django.contrib.sessions 개선
SessionBase가__bool__()을 통해 boolean evaluation을 지원합니다.
아마도 내가 보기엔
세션 객체를 파이썬의 조건식 내에서 불리언(boolean) 평가를 통해 직관적으로 다룰 수 있도록 편의성을 다듬은 것으로 보입니다. 새 __bool__() 메서드는 세션 객체 자체의 존재 여부가 아니라 내부 세션 딕셔너리의 데이터 유무를 평가합니다. 즉, request.session 객체가 이미 생성되어 있어도 저장된 키/값 데이터가 없다면 bool(request.session)은 False가 됩니다.
따라서 if request.session: 조건은 “세션 객체가 존재하는가”가 아니라 “세션 안에 데이터가 있는가”를 확인하는 표현으로 이해하는 편이 정확합니다. 세션 전체의 공백 여부를 확인하는 코드에서는 꽤 자연스럽게 사용할 수 있고, 특정 값이 필요한 로직에서는 기존처럼 해당 키의 존재 여부나 값을 명시적으로 확인하면 됩니다.
9. CSP 개선
- 새
csp_nonce_attrtemplate tag가 추가됐습니다.csp()context processor가 설정되어 있을 때<script>와<link>요소에 CSP nonce attribute를 렌더링하거나,Media객체의 asset에 nonce를 적용해 렌더링할 수 있습니다. - 새
security.W027system check도 추가됐습니다.ContentSecurityPolicyMiddleware가 활성화되어 있고 CSP 정책에CSP.NONCE가 있지만,django.template.context_processors.csp가 설정되어 있지 않으면 경고합니다. - admin template과 Django 내장 template의
<script>,<style>,<link>요소에도csp()context processor 설정 시 CSP nonce attribute가 추가됩니다.
아마도 내가 보기엔
콘텐츠 보안 정책(CSP)의 nonce 제어는 보안 품질 향상에 매우 긍정적이지만, 일반적인 템플릿이나 어드민 스태틱 자산, 폼 미디어 전반에 걸쳐 예외 없이 일관되게 적용하기엔 까다로움이 많았습니다. 이번 조치는 장고의 내장 관리자 화면과 기본 제공 템플릿 환경을 깨뜨리지 않고 견고한 CSP 보안 정책을 유지하려는 요구에 부응하기 위해 마련된 것으로 판단됩니다.
보안 규정이 엄격한 핀테크, 공공기관 플랫폼, 기업용 SaaS 솔루션 등에 유용하게 쓰일 수 있을 것 같습니다. 기존의 unsafe-inline 허용 방침을 폐기하고 엄밀한 nonce 기반 검증 체계로 마이그레이션할 때 생기는 렌더링 호환성 마찰을 경감해 줄 듯합니다.
security.W027 시스템 체크 추가는 잘못 설계되었거나 누락된 보안 설정을 로컬 부팅 시점부터 빠르게 경고하여 실수를 차단하기 위한 의도로 해석됩니다. CSP 오설정은 자칫 어플리케이션 오작동이나 심각한 XSS 취약점 노출을 초래할 수 있으므로 사전 점검 경고는 실무에서 유용할 것 같습니다.
10. Forms 개선
- form media에서 stylesheet link에 커스텀 HTML attribute를 추가할 수 있는 새 asset 객체
Stylesheet가 추가됐습니다. django.db.models.fields.BLANK_CHOICE_LABEL상수가 추가됐습니다. form choice 목록에 붙는 blank choice의 기본 라벨을 더 접근성 좋고 번역 가능한 방식으로 정의합니다. 과도기 설정인USE_BLANK_CHOICE_DASH를 사용하면 기존 기본 라벨로 되돌릴 수 있습니다.FilePathField에set_choices()메서드가 추가됐습니다.path디렉터리를 다시 스캔해 choices를 갱신할 수 있습니다. form의__init__()에서 호출하면 요청마다 choices를 새로고침할 수 있습니다.
아마도 내가 보기엔
Stylesheet 클래스의 추가는 CSP 무결성(integrity) 해시나 리소스 사전 로드(preload), 반응형 스타일 대응을 위한 미디어 속성 등을 <link> 태그에 유연하게 설정하고자 하는 프론트엔드 최적화 요구 사항에서 비롯된 것으로 생각됩니다. 커스텀 폼 위젯이나 사내 디자인 시스템 컴포넌트를 폼 미디어를 통해 삽입하는 구조에 유용할 것으로 보입니다.
BLANK_CHOICE_LABEL 도입은 선택형 폼에서 미지정(공란) 상태를 대변하던 구형 기호("---------")가 스크린 리더 인식 및 언어팩 번역 적용에 장애물이 되었던 점을 바로잡기 위한 접근성 보완 작업의 일환으로 풀이됩니다. 해외 다국어 대응 서비스나 시각 장애인을 고려한 공공 웹폼 설계에 긍정적인 영향을 줄 것 같습니다.
FilePathField.set_choices()는 동작 중인 런타임 환경에서 대상 폴더 내부의 파일 구성이 동적으로 변동할 때 이를 폼 선택지에 즉각 반영할 수 있도록 설계된 기능으로 해석됩니다. 업로드된 문서 템플릿이나 갱신되는 스크립트 목록을 백오피스에서 실시간으로 매핑해 조작하는 용도로 어울려 보입니다. 단, 파일의 실제 시스템 경로가 외부에 비치거나 권한 탈취의 빌미가 되지 않도록 실 적용 시 보안 설계에 신경을 써야 할 것 같습니다.
11. Generic Views 개선
RedirectView.preserve_request속성이 추가됐습니다. 리다이렉트 시 HTTP method와 body를 보존할 수 있으며, 이 경우302/301대신307/308상태 코드를 사용합니다.
아마도 내가 보기엔
기본적인 302 Found 리다이렉트 흐름은 클라이언트의 원래 HTTP 메서드(예: POST)를 임의로 GET으로 변경하여 재요청을 유도하는 작동적 특징이 있습니다. 이는 사용자 폼 전송 등의 일반 웹 서핑 시나리오에서는 유용하나, 페이로드가 유실되면 안 되는 웹훅이나 기계식 API 연동에서는 치명적인 결함이 될 수 있습니다. 이에 따라 preserve_request 옵션은 요청 메서드와 본문 바디 데이터를 그대로 계승하여 전달하도록 307 Temporary Redirect 나 308 Permanent Redirect 사양을 자연스레 구현하기 위한 의도일 것으로 보입니다.
여러 마이크로서비스 간 프록시 역할을 수행하는 뷰, 레거시 API 경로 이전, 특정 웹훅 목적지 변경 등 원본 데이터 유실 방지가 절대적인 백엔드 통합 상황에 적당할 듯합니다.
웹 브라우저의 일반적인 포스트 제출 후 이동 방식(PRG 패턴)에서는 기존의 302/303 리다이렉트가 더 바람직할 수 있으므로, 해당 설정은 주로 서비스 연계나 외부 API 채널 전송에 초점을 두는 편이 효과적일 것으로 생각됩니다.
12. Management Commands 개선
- Python 3.14에서 management command가
ArgumentParser의suggest_on_error=True를 기본으로 설정합니다. 잘못 입력한 subcommand나 argument choice에 대해 제안을 보여줄 수 있습니다. loaddata명령이 fixture 로딩 시m2m_changedsignal을raw=True로 호출합니다.
아마도 내가 보기엔
suggest_on_error 활성화는 오타 입력 시 유사한 명령을 자동 추측하여 제안해 주는 파이썬 3.14 내부 기능과 맞물려 개발자의 타이핑 실수를 만회하고 진입 장벽을 낮춰주는 소소한 생산성 향상 패치로 보입니다. 수많은 관리 도구와 마이그레이션 커맨드가 존재하는 중대형 인프라 관리자에게 도움을 줄 수 있을 것입니다.
loaddata 진행 시 m2m_changed의 raw=True 인자 부여는 대용량 초기 기초 데이터(fixture)를 로드할 때 동시다발적으로 발생하는 다대다 관계 변경 시그널의 부수 효과(가령 검색 인덱스 갱신, 캐시 무효화, 서드파티 API 통보 등)를 일시 비활성화할 수 있도록 분기 처리를 열어준 것으로 이해됩니다. 데이터 마이그레이션 도중 의도치 않은 대량 이벤트를 방지하는 유용한 필터로 동작할 것 같습니다.
13. Models 개선
QuerySet.in_bulk()을QuerySet.values()와QuerySet.values_list()뒤에 체이닝할 수 있게 됐습니다.- 새
JSONNullexpression이 추가됐습니다. JSON scalarnull을 명시적으로 표현할 수 있습니다. 최상위JSONField값을 저장하거나, 최상위 또는 중첩 JSON null 값을 쿼리할 때 사용할 수 있습니다. - Oracle, PostgreSQL, SQLite에서는
DecimalField.max_digits와DecimalField.decimal_places를 반드시 지정하지 않아도 됩니다. - Oracle 21c+에서
JSONField가 negative array indexing을 지원합니다. UUID4,UUID7데이터베이스 함수가 추가됐습니다.- Oracle 23ai/26ai, 정확히는 23.7+에서
GeneratedField가 stored column을 지원합니다. 즉db_persist=True를 사용할 수 있습니다. m2m_changedsignal이raw인자를 받습니다.- SQLite에서
StringAgg가 기본 delimiterValue(",")를 사용할 때distinct=True를 지원합니다. QuerySet.totally_ordered속성이 추가됐습니다. QuerySet이 정렬되어 있고 그 정렬이 결정적인지 여부를True/False로 반환합니다.BitAnd,BitOr,BitXoraggregate가 일반 모델 aggregate로 추가됐습니다. 이전에는contrib.postgres에만 있었습니다.django.db.models.BinaryField가 Base64 입력을 더 엄격하게 검증합니다. 잘못된 Base64 문자열은 조용히 허용되지 않고ValidationError를 발생시킵니다.
아마도 내가 보기엔
이 개선 항목들은 단일의 거대한 혁신이라기보다는 데이터베이스 공급자별 ORM 파편화를 다듬고, 파이썬 코드 레벨에서 SQL 표준의 엣지 케이스들을 보다 명확히 해결하기 위한 편의 패치 모음집으로 읽힙니다.
JSONNull 지원의 경우 데이터베이스 고유의 NULL 필드 여부와 JSON 포맷 내의 null 값 사이의 고질적인 파이썬 None 타입 충돌 문제를 방지하기 위해 마련된 주요 개선책으로 보입니다. JSON 필드에 원시(scalar) null 값을 주입하거나 비교 쿼리를 짤 때 발생하던 모호함을 해소해 줄 수 있으므로, 대외 API 규격을 JSON으로 수용하는 시스템이나 유연한 이벤트 저장소를 운용하는 데 적절할 듯합니다.
UUID7 데이터베이스 레벨 생성이 탑재된 점도 주목할 만합니다. 타임스탬프와 난수가 혼합된 UUID7은 시계열에 따른 자연 정렬을 지원하여, 데이터가 무작위로 분산되는 UUID4에 비해 DB 인덱스 로컬리티(locality) 성능을 대폭 보완할 수 있을 것으로 예상됩니다. 로그 테이블이나 실시간 메시지 큐 등 대량 유입 적재 환경에 적합해 보입니다.
QuerySet.totally_ordered 검사는 페이징(pagination) 처리 과정에서 결과 행의 유일무이하고 고정된 정렬 순서를 객관적으로 검증하기 위해 기획된 지표로 분석됩니다. 무작위 정렬값으로 인해 다다음 페이지로 넘어갈 때 특정 행이 중복되어 읽히거나 유실되는 문제를 방지할 수 있으므로 커서 기반 무한 스크롤 설계나 배치 내보내기 시나리오에 요긴할 것 같습니다.
비트 연산 집계(BitAnd, BitOr, BitXor)의 표준 ORM 편입 역시 특정 플랫폼에 고착되어 있던 최적화 성능을 타 DB 환경으로 확장하는 유연성 확보에 방점을 둔 것 같습니다. 권한 마스크 필터링이나 상태 전이 검사 등에 유효할 것으로 여겨집니다.
BinaryField의 Base64 엄격 검사 조치는 잘못된 인코딩 텍스트가 DB에 보존되어 추후 디코딩 장애를 일으키는 불상사를 줄이고자 안전 벨트를 단단히 조인 개념으로 이해됩니다. 토큰 저장이나 이미지 바이너리 임시 수신 등 엄격한 복합 데이터를 처리할 때 요긴할 것 같습니다.
14. Requests and Responses 개선
HttpRequest.multipart_parser_class를 커스터마이즈해 다른 multipart parser class를 사용할 수 있게 됐습니다.HttpResponseRedirect와 그 하위 클래스, 그리고redirect()shortcut이max_length인자를 받습니다. 기본 최대 URL 길이 제한을 덮어쓸 수 있습니다.
아마도 내가 보기엔
멀티파트 파서의 커스터마이징 허용은 Django에 기본 내장된 파일 업로드 파이프라인의 제약을 넘어, 실시간 바이러스 정밀 스캔이나 비동기 스트리밍 멀티플렉싱 등 엔터프라이즈급 파일 처리 특화 아키텍처를 유연하게 얹을 수 있도록 통로를 개척해 준 조치로 보입니다.
리다이렉트 시의 max_length 허용치는 단일 통합 로그인(SSO) 토큰 연동이나 서명된 길고 긴 쿼리 스트링 매개변수 이동 등 모던 엔터프라이즈 협업 프로토콜에서 발생하는 긴 URL 잘림 에러를 우회하도록 설계된 구제책으로 분석됩니다. 다만, 과한 길이의 주소 전송은 중간 프록시나 레거시 방화벽에서 커트될 소지가 있으니 아주 제한적인 경우에만 유의해 쓰는 편이 안전해 보입니다.
15. Serialization 개선
natural_key()메서드를 정의한 model subclass가 빈 tuple()을 반환하면 natural key serialization을 사용하지 않도록 opt-out할 수 있습니다. 이 경우dumpdata --natural-primary를 사용할 때 primary key가 직렬화됩니다.- XML deserializer가 예상치 못한 중첩 태그를 만나면
SuspiciousOperation을 발생시킵니다.
아마도 내가 보기엔
natural_key opt-out 기능은 복잡하게 꼬인 테이블 상속 계층 구조나 공통 골격 모델로부터 불가피하게 natural_key() 로직을 물려받았지만, 특정 하위 자식 테이블만큼은 일반 기본 키(Primary Key) 정수로 직렬화하고 싶을 때 유용할 것으로 보입니다. 개발 시 테스트 데이터를 관리하거나 일시적인 스테이징 마이그레이션 중 충돌을 모면하는 튜닝용으로 어울릴 듯합니다.
XML 파서의 SuspiciousOperation 즉시 예외 처리는 변조된 XML 레이아웃을 악용해 파싱 자원을 고갈시키거나 허가되지 않은 내부 엔티티를 조회하려는 침입 위협(예: XXE 공격 등)을 원천 차단하기 위해 추가된 단단한 보안 마감으로 해석됩니다. 외부 레거시 연동이 잦은 레거시 마이그레이션 백엔드에 꼭 필요할 것 같은 기능입니다.
16. Tasks 개선
task()데코레이터가**kwargs를 받을 수 있게 됐습니다. 이 값들은 backend의task_class로 전달됩니다.Task와TaskResult인스턴스를 pickle/unpickle할 수 있습니다.
아마도 내가 보기엔
장고에 빌트인되기 시작한 비동기 작업 기능들을 보다 다양한 환경에 맞춰 다듬기 위한 개선으로 파악됩니다. task() 데코레이터에서 임의의 키워드 매개변수(**kwargs)를 넘겨받을 수 있도록 규격을 유연화함으로써, 서드파티 큐 백엔드 고유의 우선순위 설정이나 재시도 주기 등을 뷰에서 유연하게 지시할 수 있을 것으로 생각됩니다.
Task와 결과 객체의 파이썬 pickle 직렬화 지원도 분산 서버 분할 및 프로세스 간 원격 프로시저 호출(RPC) 데이터 무압축 적재에 기여하기 위한 기술적 초석으로 보입니다. 대규모 비동기 워커 노드를 운영하는 구성에 어울릴 것으로 생각됩니다.
다만, 피클(pickle) 포맷 자체가 가지고 있는 태생적인 역직렬화 보안 위험성(Remote Code Execution 등)이 있으므로 시스템 외부망으로부터 들어오는 출처 미상의 페이로드를 함부로 직렬화 해제하는 구조는 지양해야 할 것 같으며, 내부 보안 영역(VPC 내의 레디스 등) 내부에서만 활용을 제한하는 것이 안전할 듯합니다.
17. Tests 개선
assertContains()와assertNotContains()를 같은StreamingHttpResponse에 여러 번 호출할 수 있게 됐습니다. 이전에는 streaming response content가 한 번 소비되면 이후 호출이 실패할 수 있었습니다.
아마도 내가 보기엔
StreamingHttpResponse는 기존 파일 형태의 일반 HTTP 응답 객체와 달리 데이터 스트림이 일회성으로 소비되는 제네레이터 특성이 있어, 테스트 단언문(assertion)이 최초 실행된 후 내부 리소스가 고갈되는 등 이중 검증이 곤란한 문제를 풀기 위해 마련된 듯합니다.
웹 브라우저로 실시간 실어 나르는 대용량 CSV 출력, 이벤트 스트림 전송(SSE), 스트리밍 다운로드 API 등을 테스트하는 환경에 무척 편리할 것 같습니다. 하나의 동일한 가상 스트림 응답 속에서 특정 중요 텍스트가 온전히 포함되었는지 혹은 걸러졌는지를 연속해서 단언할 수 있어, 테스트 케이스의 신뢰도와 가독성이 동시에 높아질 것으로 여겨집니다.
18. Utilities 개선
parse_duration()이 ISO 8601 week 형식의 기간 표현, 즉PnW를 지원합니다.
아마도 내가 보기엔
시간이나 기간을 다루는 글로벌 표준 규격인 ISO 8601의 duration(지속 시간) 표기 방식 중 ‘주(Week)‘를 의미하는 PnW 파싱을 완벽히 흡수하여, 전반적인 스펙 커버리지를 채우기 위한 유틸 보강으로 추측됩니다.
구독 만료일이나 정기 세금 계산 주기 등 주 단위 스케줄이 빈번한 대외 API 응답 값을 직접 파이썬 datetime 데이터로 복구해야 하는 상호 운용성 컴포넌트 개발에 적합해 보입니다. 커스텀 정규식이나 유동 파서 라이브러리에 굳이 의존하지 않고 내장 유틸리티로 깔끔하게 처리할 수 있어 시스템이 한결 간결해질 것으로 기대됩니다.