Python Django - QueryDict 다루기
[오류 개선]
querydict (데이터 셋)에서 필드값을 바로 가져올 수 없다.
rows = <Model 명>.objects.all()
print(rows.id) # error 발생 (QueryDict object has not arrtibute 'id')
for row in rows 로 각 row에 대해서 필드값을 가져올 수 있다
querydict (데이터 셋)에서 필드를 바로 참조할 수 없다.
rows = <Model 명>.objects.all()
for row in rows:
print(row.id) # 정상적으로 출력
또는 rows.values 나 rows.values_list(<필드명>) 의 메서드를 통해서 필드값을 가져올 수 있다.
rows = <Model 명>.objects.all()
print(rows.values) # dict 형태
print(rows.values_list('id', 'username')) # (1, 'admin',), (2, 'test1',), (3, 'test2',) 형태
print(rows.values_list('id', flat=True)) # [1, 2, 3] 형태
Python Django - ReturnDict 다루기
[오류 개선]
문제 발생
게시물 데이터를 직렬화하여 Response를 할 때 이 데이터에 별점 데이터를 추가하고 싶었다. serializer.data의 리턴 형태가 dict 자료형이기 때문에 serializer.data[”Key”] = <Value> 로 작성하여 데이터를 추가하고 싶었으나 원하는대로 동작하지 않았다.
원인
serializer.data의 return 값인 ReturnDict는 immutable한 객체이다. (불변 객체)
따라서 serializer.data에 추가적인 조작을 할 수 없다. (추가 or 수정 or 삭제 등)
해결
특정 변수에 깊은 복사를 진행한다.
그리고 그 변수에 조작을 가한 후 return 해준다.
# 깊은 복사 (deep copy)
data = serializer.data
# data에 key-value 쌍 추가
data["star_score"] = star_score
# 조작을 마친 data를 Response 객체에 담는다
return Response(data, status=status.HTTP_200_OK)
별점 데이터를 담는 방식
[기술적 의사결정]
별점 데이터를 상세 조회 데이터에 추가하기 위해 다양한 방법이 논의됐다.
① 직접 데이터를 조회 후 계산
# 전체 별점 데이터
stars = list(game.stars.all().values('star'))
# stars의 형태가 querydict 이므로 ['star']를 통해 값만 리스트에 담는다
star_list = [d['star'] for d in stars]
# round()를 통해 소수점 첫째 자리까지만 / 전체 별점을 별점 row 수로 나눔(평균 구하기)
star_score = round(sum(star_list)/len(star_list), 1)
② QuerySet API 사용 (Django 제공)
avg_star = game.stars.aggregate(Avg('star'))['star__avg']
avg_star = game.stars.annotate(Avg('star')).values('star__avg').first()['star__avg']
aggregate 와 annotate 방식이 있다.
game.stars (QueryDict)에 대해 두 메서드를 적용하는 방식
①, ② 중 ① 방식을 우선 구현했기 때문에 ①으로 진행했고, 추후 리팩토링 과정에서 수정될 수 있음.
프론트 구상
[메모/생각정리]
'프로젝트' 카테고리의 다른 글
[TIL] 20240522 68일차 (0) | 2024.05.22 |
---|---|
[TIL] 20240521 67일차 (0) | 2024.05.21 |
20240513 ~ 20240517 13주차 정리 (0) | 2024.05.18 |
[TIL] 20240517 65일차 (0) | 2024.05.18 |
[TIL] 20240516 64일차 (0) | 2024.05.16 |