Programming-[Backend]/Django 56

Django로 프로젝트 세팅 with DRF, mysql, viewSet, pyTest

1. 프로젝트 생성, DB 연결 python 3.12.2, pyCharm을 통해서 프로젝트 생성 pip install poetry poetry init poetry add djangorestframework poetry add django-environ .env 파일을 만든다. SECRET_KEY와 DB 정보 등을 .env에 숨긴다. SECRET_KEY=.. DB_NAME=. DB_PORT=. DB_USER=. DB_PASSWORD=. DB_HOST=. settings.py에 아래처럼 설정한다. __file__은 코드가 작성된 현재 파일을 의미한다. os.path.abspath로 절대경로를 가져온 뒤, os.path.dirname으로 상위 경로의 디렉토리 이름을 BASE_DIR로 잡는다. BASE_DIR..

Django nested Serializer update 시 선언되지 않은 field 문제

1. 문제점 부모 - 자식의 구조를 갖는 Nested된 Serializer 구조를 사용했는데, update 메서드를 Django에서 지원하지 않는다고 하면서 아래 같은 에러 메시지가 뜬다. AssertionError: The `.update()` method does not support writable nested fields by default. Write an explicit `.update()` method for serializer `...`, or set `read_only=True` on nested serializer fields. 2. 해결 방안 필드를 사용할 때 반드시 Model에서 역참조로 related_name 값으로 정의한 이름으로 사용해주어야 한다. School : People ..

reverse relationship: _set 호출 시 get_ 메서드에서 N+1 발생

문제 reverse relationship을 가진 속성값을 _set을 통해서 호출할 때, get_ 메서드에서 N+1 문제가 발생했다. 해결 예를 들면 아래 예시 코드에서, student_set을 통해 Related Manager로 set을 불러올 때 .all()을 사용하면 안되고 .first()등으로 특정 로우를 한정해야한다. 그렇지 않으면 여러 개의 School -> 여러 개의 Student가 호출되면서 N+1 문제가 필연적으로 발생한다. class SchoolListSerializer(serializers.ModelSerializer): latest_student_name = serializers.SerializerMethodField() def get_latest_student_name(self, ..

API Throughput, health check fail: async 요청이 한 번에 많이 들어올 때

문제 및 원인 특정 컨테이너의 health check가 주기적으로 fail이 발생했다. 다행히 운영환경은 아니고 테스트 환경이였는데, 로그를 추적해보니 클라이언트 쪽에서 비동기 요청을 한 번에 10개 가량 요청하여(10개 이상/ 1초) 서버에 요청 처리가 쌓인 상태에서 /health 로 헬스 체크가 들어오면 헬스 체크에 실패하는 상황이였다. 문제는 헬스 체크 실패 시 해당 컨테이너를 재시작하는 설정이 적용되어 있어서 컨테이너가 죽다보니 클라이언트에서도 문제가 있다고 알려주었다. 그리고 monitoring 툴인 Pixie로 HTTP 지연을 관찰했을 때 순간적으로 지연이 엄청 늘어나는 것을 볼 수 있었다. 해결 및 원리 1. gunicorn worker, thread 개수 늘리기 파이썬은 인터프리터로 싱글 ..

[TIL] Django Restframework Exception Handler 개요

1. Exception Handler 설정 Django에서 exception handler는 settings.py 파일의 RESTFRAMEWORK 설정에서 경로를 지정해줄 수 있다. 기본적으로는 Class를 지정하여 사용하며 exception_handler.ExceptionHandler를 상속받아 메서드들을 override한다. from rest_framework.views import exception_handler class CustomExceptionHandler(exception_handler.ExceptionHandler): def handle_exception(self, exc): # Custom logic to handle the exception # Return a custom respon..

[TIL] Django Cache 개요

1. Cache 설정 Caching은 잦은 접근이 예상되어 데이터베이스에 직접 접근하지 않고 Memchached나 Redis 같은 속도가 빠른 저장소에 데이터를 저장해놓는 방식이다. Django에서는 아래와 같이 settings.py에 설정하여 사용할 수 있다. CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', }, 'redis': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://localhost:6379/1', 'OPTIONS': { 'CLIENT_CLASS': 'dj..

[TIL] Django ListSerializer 활용, List Update/Create

viewset을 이용하면 list, create API 끼리 묶이고, retrieve, update, destroy 끼리 detail로 묶여서 동작한다. 여기서 detail쪽은 반드시 어떤 테이블의 레코드와 일치하는 특정 인스턴스를 가리키기 위해서 아래와 같이 pk 값을 써줘야한다. 특정 학생 정보를 업데이트하기 위해 student의 pk값을 받는다. https://django.school//student/ 그래서 만약 여러 레코드(인스턴스)를 한 번에 update하고 싶다면 ListSerializer를 구성하여 처리해야한다. Serialier 구성 class StudentListSerializer(serializers.ListSerializer): def update(self, instance: Lis..

[TIL] django, MYSQL, postgresql db collation

collation은 DB에 입력되는 문자의 중복을 어떻게 볼 지 설정하는 것이다. case-insensitive는 'Fred'와 'fred'를 같은 문자로 본다. case-sensitive는 대소문자를 다르게 본다. DB provider에 따라 옵션의 이름이 각각 다르다. django 홈페이지에 나온 MYSQL에 대한 문서를 보면 default collation으로 속성값들이 있는 것을 볼 수 있다. 기본값이 정해져있다. (아래는 MYSQL) https://dev.mysql.com/doc/refman/8.0/en/charset-general.html 장고에서는 모델을 만들 때 TextField, CharField의 인자값으로 db_collation 인자를 설정해줄 수 있다. 그리고 데이터 정렬의 기준이 ..

[탐험] Django admin에서 view, template, render 다루기. 비동기 처리 버튼 만들기

1. 목표 Django admin 페이지로 어떤 파일들을 모아서 압축 파일을 생성하는 비동기 작업이 완료되면, 그것들을 다운로드 받을 수 있는 페이지 제작 2. 구조 3. 구조 설명 3-1. django admin django admin은 모델을 생성하고 admin에 등록하면, admin 주소로 들어오는 요청을 보낼 수 있는 FORM과 화면을 구성하는 TEMPLATE을 간단히 만들 수 있도록 해준다. @admin.register로 admin에 모델을 등록하고 get_urls로 path와 일치하는 요청이 들어왔을 때 특정 view로 가서 로직을 처리하게 할 수 있다. meta_data로 app_label값과 model_name값을 불러와서 view의 name을 동적으로 만들어줄 수 있다. 이 name값은 ..