Django 4.1 릴리스와 주요 변경 사항

이 글에서는 Django 4.1에 추가된 기능과 바뀐 점을 알아보려 합니다. Django 4.1 release notes를 참고하였습니다.

Django는 3년 마다 LTS를 위해 메이저 버전을 하나씩 올리고, 8개월마다 마이너 버전을 올립니다. 현재 LTS 버전은 3.2.x입니다. 이번에 출시한 4.1은 LTS 버전은 아닙니다.

출처: Django 다운로드 페이지

파이썬 호환성

Django 4.1은 파이썬 3.8과 3.9, 3.10을 지원합니다. 각 버전의 마지막 릴리스를 사용하기를 권장합니다.

44BITS 소식과 클라우드 뉴스를 전해드립니다. 지금 5,000명 이상의 구독자와 함께 하고 있습니다 📮

새 기능

클래스 기반 뷰에 적용할 수 있는 비동기 핸들러

Django 3.1부터 비동기 뷰가 도입됐지만 함수 기반 뷰에서만 사용할 수 있었는데요. 4.1부터는 클래스 기반 뷰에도 사용할 수 있습니다.

class BlogView(View)
    async def get(self, request, *args, **kwargs):
        await asyncio.sleep(5)
        return HttpResponse('This is an async response')

클래스 기반 뷰에 적용하는 비동기 핸들러에 대한 자세한 내용은 Asynchronous class-based views 문서를 참고하세요.

비동기식 ORM 인터페이스

비동기 처리용 ORM 인터페이스를 지원합니다. 기존 ORM 메서드 앞에 a를 붙은 형태의 메서드를 사용하면 됩니다. 이를테면, create 대신 acreate, first 대신 afirst 처럼요.

새 쿼리셋을 반환하는 메서드들은 별도의 인터페이스를 만들지 않았습니다. filterexclude, annotate 등은 비동기 코드에서 그대로 사용해도 됩니다.

async for post in Posts.objects.filter(datetime__year=2022):
    tag = await post.tags.afirst()

하지만, 데이터베이스 연산은 아직 동기 방식으로 처리됩니다. 새 인터페이스는 기존 연산에 sync_to_async()를 감싸두었을 뿐이고요. SQL 컴파일러와 데이터베이스 드라이버에 이르기까지 비동기 지원 작업을 열심히 진행 중이라고 합니다.

그럼 비동기 ORM 인터페이스를 사용할 필요가 없을까요? 비동기 코드나 비동기 뷰에서 동기식 ORM 인터페이스를 호출하면 SynchronousOnlyOperation 오류가 발생하니, 이때 비동기식 ORM 인터페이스를 사용하면 되겠습니다. 게다가 미리 비동기식 인터페이스를 사용해두면, 추후 데이터베이스 연산이 비동기 방식으로 처리되었을 때 급하게 코드를 수정하지 않아도 되겠고요. 그리고 트랜잭션 역시 비동기 처리를 지원하지 않습니다. 트랜잭션을 사용해야 한다면 해당 코드를 분리한 다음 sync_to_async 함수로 감싸서 호출해야 합니다.

비동기식 ORM 인터페이스에 대한 자세한 내용은 Asynchronous queries 문서를 참고하세요.

모델 제약 조건을 유효성 검증 과정에 검사

Checkunique, exclusion 같은 데이터베이스 제약 조건을 모델 유효성 검증 과정에서 검사합니다. 만약 검사에 실패하면 ValidationError 예외가 발생합니다.

Django 4.0까지는 모델 유효성 과정에 검사하지 않았고, 데이터베이스에 저장할 때 IntegrityError 예외를 발생시켰습니다.

접근성이 향상된 폼 렌더링

스크린 리더 같은 장치를 사용하는 사용자들에게도 접근하기 편한 폼을 만들고자 <div> 기반의 폼 템플릿을 제공합니다. Django 5.0에서는 새 폼 템플릿을 기본으로 사용하지만 아직은 그렇지 않으므로, 이를 적용하고 싶다면 FORM_RENDERER 설정 값을 다음처럼 정의하세요.

FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"

CsrfViewMiddleware 는 더이상 CSRF 쿠키를 마스킹하지 않습니다. 만약 Django 4.1 이전 버전을 Django 4.1로 업그레이드하고 있다면 호환성을 위해 CSRF_COOKIE_MASKEDTrue로 설정하고, 업그레이드가 끝난 후 CSRF_COOKIE_MASKED 설정을 지우기 바랍니다.

Django 5.0에서 CSRF_COOKIE_MASKED 설정은 사라질 예정입니다.

자잘한 변경

관리자 화면(django.contrib.admin)

FieldListFilter를 정의할 때 __in 룩업을 사용할 수 있습니다. 다음과 같이 expected_parameters 메서드를 오버라이드하면 됩니다.

class FilterWithCustomSeparator(admin.FieldListFilter):
    # custom list separator that should be used to separate values.
    list_separator = '|'

    def __init__(self, field, request, params, model, model_admin, field_path):
        self.lookup_kwarg = '%s__in' % field_path
        super().__init__(field, request, params, model, model_admin, field_path)

    def expected_parameters(self):
        return [self.lookup_kwarg]

자세한 내용은 ModelAdmin List Filters 문서의 해당 부분을 참고하세요.

PBKDF2 해시 반복 횟수

PBKDF2 해시의 반복 횟수가 320,000회에서 390,000회로 증가했습니다.

사용자 속성이 원격 백엔드와 싱크

RemoteUserBackend.configure_user() 메서드를 사용하면 LDAP 같은 원격 백엔드의 사용자 속성과 동기화할 수 있습니다.

사이트맵에 <lastmod> 추가

사이트맵 생성시 기본으로 <lastmod> 타임스탬프 값을 추가합니다. get_latest_lastmod()를 사용합니다.

관리 명령어

마이그레이션

모델

요청과 응답

보안

테스트

하위 호환되지 않는 기능

django.contrib.gis

데이터베이스

중단 예정인 기능

GET 기반의 로그아웃

내장 로그아웃 뷰가 GET 방식에서 POST 방식으로 바뀌었습니다.

기타

삭제된 기능

마치며

요약은 여기까지입니다. 개인적으론 중요하지 않아 보여서 적지 않은 내용이 여러분에겐 더 중요할 수도 있으니, Django 4.1 공식 릴리스 노트를 한 번 살펴보시길 추천합니다.

구글 앱스 스크립트(Google Apps Script) 외부에서 실행하기

🗒 기사, 2018-08-02 - 구글 앱스 스크립트를 사용하면 구글 드라이브나 G 스위트를 자동화할 수 있습니다. 이 글에서는 간단한 구글 앱스 스크립트를 작성하고, 이 스크립트를 구글 드라이브 외부 환경에서 실행하는 방법을 소개합니다.

깃허브(GitHub), L4 로드 밸런서 GLB 디렉터 오픈소스로 공개

🗞 새소식, 2018-08-14 - 깃허브(GitHub)에서는 지난 8월 8일 GLB 디렉터(Github Load Balancer Director)를 오픈소스로 공개하였습니다.

만들면서 이해하는 도커(Docker) 이미지: 도커 이미지 빌드 원리와 OverlayFS

🗒 기사, 2019-12-24 - 도커 이미지는 유니온 마운트 기술을 활용해 계층화된 레이어들로 구성되며, 도커 레지스트리를 사용해 쉽고 효율적인 공유를 가능하게 해줍니다. 이 글에서는 도커 이미지가 저장되는 방식과 도커 이미지 빌드의 원리, 그리고 그 바탕이 되는 유니온 마운트 구현체의 하나인 OverlayFS에 대해서 알아봅니다.