오늘 학습 내용 ✅
파이썬 내장 리플렉션 도구
setattr
- setattr(객체, "속성명", 값)
- 문자열로 된 속성 이름을 사용해서 객체의 속성 값을 설정한다
question.title = "새 제목"
question.content = "새 내용"
setattr(question, "title", "새 제목")
setattr(question, "content", "새 내용")
getattr
- getattr(객체, "속성명") / getattr(객체, "속성명", 기본값)
- 같이 쓰이는 친구
value = getattr(question, "title")
value = getattr(question, "not_exist", None)
for field in ("title", "content"):
old_value = getattr(question, field)
new_value = validated_data.get(field)
if new_value is not None and old_value != new_value:
setattr(question, field, new_value)
hasattr
- hasattr(객체, "속성명")
- 존재 여부 확인
- if hasattr(question, "title"):
- Django Model에서는 거의 안 씀
- Serializer / 일반 객체 / 동적 객체에서 가끔 사용
| 함수 | 역할 | 한 줄 설명 |
|---|
getattr | 조회 | 문자열로 속성 값을 가져옴 |
setattr | 설정 | 문자열로 속성 값을 설정 |
hasattr | 확인 | 속성이 존재하는지 확인 |
| 함수 | 용도 |
|---|
setattr | PATCH / 동적 수정 |
getattr | 비교 / 조건 처리 |
isinstance | 타입 검사 (권한, 유저 등) |
callable | 함수인지 확인 |
vars() | 객체의 속성 dict |
__dict__ | 내부 속성 접근 |
delete_ids
from rest_framework import serializers
from apps.qna.models import QuestionImage
class QuestionImagePatchSerializer(serializers.Serializer[QuestionImage]):
delete_ids = serializers.ListField(
child=serializers.IntegerField(),
required=False,
default=list,
)
add_urls = serializers.ListField(
child=serializers.URLField(),
required=False,
default=list,
)
delete_ids
- QuestionImage.id (PK)
- delete_ids에 들어갈 값은 전부 “프론트엔드가 결정”하고 백엔드는 “검증 + 실행”만 한다.
PR Riview
- setattr 이후 save()를 호출하면 변경되지 않은 필드도 함께 업데이트될 수 있어
- 수정된 필드만 update_fields로 지정하는 방식도 고려해볼 수 있을 것 같습니다.
update_fields: list[str] = []
for field in ("title", "content", "category"):
if field in validated_data:
setattr(question, field, validated_data[field])
update_fields.append(field)
if update_fields:
question.save(update_fields=update_fields)
- 문제: 현제 기본적으로 question.save()의 대상이 모든 필드
- Django는 변경여부를 추적하지 않기 때문에 변경하지 않은 필드도 업데이트 쿼리에 포함 가능
- 이렇게 진행되면 수정되지 않은 필드까지 수정되기 때문에 불필요한 업데이트 발생
- 나중에 업데이트 추적하기 어려움
- 해결: update_fields를 이용해서 변경된 필드만 따로 저장
새롭게 알게된 내용 ✅
- context={"request": request}
- Serializer 내부에서 현재 요청 정보에 접근 가능하게 함
오늘 발생한 문제(발생 했다면) ✅