새롭게 알게 된 코드
2025/11/21
DRF
many=True
- 기본값: False
- 여러 개의 객체(리스트)를 직렬화할 때 사용
- QuerySet 같이 여러 개의 객체를 Serializer로 처리할 때 사용
- ex. Post.objects.all(), User.objects.filter(...)
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
만약 many=True 없이 QuerySet을 넘기면?
- TypeError: 'Post' object is not iterable
- multiple objects인데 single object로 받으려고 해서 에러
raise_exception=True
- 기본값: False
- 검증 실패 시 예외를 자동으로 발생
- Serializer 검증(.is_valid()) 할 때 사용
- 잘못된 요청이 들어오면 DRF가 자동으로 400 Bad Request 응답을 보내게 하고 싶을 때
- 직접 if문으로 검사할 필요가 없어져서 개발자의 코드가 깔끔해짐.
serializer = UserSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
partial=True
- 기본값: False
- PATCH(부분 업데이트)에서 사용하는 옵션
- partial=False → 모든 필드가 유효하게 들어와야 함.
- partial=True → 일부 필드만 들어와도 OK.
{
"nickname": "새닉네임"
}
serializer = UserSerializer(user, data=request.data, partial=True)
만약 partial=True 없이 PATCH 요청을 하면?
- "password field is required" 같은 에러 발생
2025/11/23
get_user_model()
- 현재 프로젝트에서 사용 중인 “User 모델”을 가져오는 Django 함수
- Django가 커스텀 User 모델을 사용하더라도, 항상 올바른 User 모델을 가져오게 해주는 안전한 함수
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
User = get_user_model()
User 모델을 만든 적이 없는데 왜 ForeignKey로 연결이 가능한가?
from django.contrib.auth import get_user_model
User = get_user_model()
class Blog(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
커스텀 User 모델을 만들면?
- settings.py 에서
AUTH_USER_MODEL = "accounts.CustomUser" 이렇게 설정
- get_user_model()은 커스텀 User를 반환하고, 외래키도 자동으로 그 모델로 연결됨.
read_only_fields
2025/11/25
유용한 날짜 함수
from datetime import datetime, timedelta
import calendar
def get_daily_range():
today = datetime.now().date()
start = datetime.combine(today, datetime.min.time())
end = datetime.combine(today, datetime.max.time())
return start, end
def get_last_day_range():
yesterday = datetime.now().date() - timedelta(days=1)
start = datetime.combine(yesterday, datetime.min.time())
end = datetime.combine(yesterday, datetime.max.time())
return start, end
def get_week_range():
today = datetime.now().date()
start = today - timedelta(days=today.weekday())
end = start + timedelta(days=6)
return datetime.combine(start, datetime.min.time()), datetime.combine(end, datetime.max.time())
def get_last_week_range():
today = datetime.now().date()
end = today - timedelta(days=today.weekday() + 1)
start = end - timedelta(days=6)
return datetime.combine(start, datetime.min.time()), datetime.combine(end, datetime.max.time())
def get_month_range():
today = datetime.now().date()
start = today.replace(day=1)
last_day = calendar.monthrange(today.year, today.month)[1]
end = today.replace(day=last_day)
return datetime.combine(start, datetime.min.time()), datetime.combine(end, datetime.max.time())
def get_last_month_range():
today = datetime.now().date()
first_day_this_month = today.replace(day=1)
last_month_end = first_day_this_month - timedelta(days=1)
start = last_month_end.replace(day=1)
end = last_month_end
return datetime.combine(start, datetime.min.time()), datetime.combine(end, datetime.max.time())
def str(self)
dategte / datelte
- 그냥 변수 이름이 아닌 실제 Django ORM 기능(lookup)
transacted_at__date
- transacted_at → DateTimeField
__date → datetime에서 날짜(date)만 추출
__gte, __lte → 비교 연산 조건
transacted_at__date__gte=self.start_date
- "transacted_at 의 날짜 부분이 start_date 이상인 데이터"
- 즉, 실제로 DB에서 날짜만 비교하도록 만들어주는 기능
| 형태 | 역할 |
|---|
field__gte | field ≥ value |
field__lte | field ≤ value |
field__contains | LIKE %value% |
field__date | datetime → 날짜 변환 |
field__year | datetime.year |
field__month | datetime.month |
field__day | datetime.day |
field__date__range | 날짜 범위 |
새롭게 알게 된 이론
2025/11/27
| 구분 | 언제 쓰는가 | 어디에서 값이 오는가 | 예시 |
|---|
| request.query_params | GET 요청 | URL 쿼리스트링 | /analysis/list/?period=DAILY |
| request.data | POST/PUT/PATCH 요청 | JSON body, form-data | POST로 분석 생성 요청 |
query_params
query_params = URL 뒤에 붙은 ?key=value 값을 가져오는 DRF 객체
- Django REST Framework(DRF) 에서 GET 요청의 쿼리스트링(parameters)을 가져올 때 사용하는 객체
- Django에는 원래 request.GET 하지만 DRF는 API 스타일로 통일하기 위해 request.query_params
ex.
- 요청: GET /analysis/api/list/?period=DAILY&type=graph
- period=DAILY / type=graph -> query params(쿼리 파라미터)
- period = self.request.query_params.get("period") -> 결과: "DAILY"
data
- request.data는 POST 요청 body에서 값을 꺼내는 역할
POST /analysis/api/create/
Content-Type: application/json
{
"type": "CATEGORY",
"about": "MONTHLY",
"description": "이번달 분석입니다"
}
- analysis_type = request.data.get("type") -> CATEGORY
Django(DRF)에서의 용어 비교
| 가져오는 값 | 예시 | 접근 방식 |
|---|
| URL Path Params | /analysis/123/ → 123 | kwargs["id"] |
| Query Params | ?period=DAILY | request.query_params["period"] |
| Body Params (POST) | form/json 데이터 | request.data["field"] |