어제 해결하지 못한 nested_serializer 처리 방식을 멘토님께 질문드렸고 해결했다! (이때는 몰랐죠.. 3 am까지 하게 될줄..)
https://www.django-rest-framework.org/api-guide/serializers/#dealing-with-nested-objects
Serializers - Django REST framework
www.django-rest-framework.org
여기에 잘 나와있었다. 그래서 일단 patch 는 가능할 것 같다. 근데 이제 문제는 patch 일 때는 serailizer 를 사용해야하고, 나머지의 경우에는 charfield 를 사용하도록 serializer 를 만들어볼 생각이다.
이런 식으로 작성했고,
pytest 를 돌려봤을 때 꽤나 괜찮게 나오는 것을 확인할 수 있었다.
이제 저 에러가 나는 부분들을 확인하면 될 것 같다.
일단 마지막과 두번째는 아직 nested에서 updated_order 만 데려온게 아니라서 그렇다쳐도..
첫번째는 에러가 나면 안되는 사항이기에 먼저 해결해볼 예정이다.
스윽 살펴보니 validation 에서 data['order'] 가 없다고 하기에 디버그 모드를 키려고 했으나
생각해보니 이건 pytest 환경이라 디버그를 하기 위해 찾아봤다.
pytest.ini 파일에 debug_mode 옵션 True 로 하면 된다는데 어떻게 쓰는 건지 모르겠어서 일단 빨리 끝내고자 다른 방법을 강구해봤다. 였는데 자료를 찾았다.
https://stackoverflow.com/questions/63619498/vs-code-python-debugging-pytest-test-with-the-debugger
VS Code / Python / Debugging pytest Test with the Debugger
How can I get VS Code to put me into the debugger at the point of failure when running tests with pytest? Pytest catches all errors and asserts, and VS code invokes the debugger only on uncaught er...
stackoverflow.com
저 옆에 플라스크 버튼을 누르니 실행이 되었다.
신기했다.
보아하니 중간에 order 가 사라졌다.
찾아보니 serializerMethodField 의 경우 애초에 read-only 특성을 가진다고 되어있다.
즉 이렇게 해결하면 안된다.
^^b
시도 1 - patch 용 serializer 를 만들자
이 친구의 경우에 일단 기존 serializer 와 너무 유사한 점이 많다. 로직도 많이 겹치고 만들다가 이건 아닌 것 같아서 접었다.
두번째 이유는 order 의 값자체가 저 serializer 값인데, 모델과 serializer 가 달라서 저장이 안된다. 에러가 떴던 것 같다.
시도 2 - 그냥 view 에 validation 로직을 넣는다.
이 친구는.. 지금까지 열심히 써왔는데 뭔가 view 에 있어서 동떨어진 느낌이 들어서..
여러번의 이런저런 시도끝에 생각한 임시방편을 생각해냈다.
serializer 에 patch_order 필드를 생성한다.
그리고 patch 를 받으면 data['order'] 에 updated_order 의 값을 넣는다.
그후 원래의 data['order']의 값을 data['patch_order'] 의 값에 넣는다.
대략 원하는 행동은..
patch_order 에서 validation 이 맞지 않으면, 업데이트가 되지 않는거고..
patch_order 의 validation 이 지났다면, 업데이트가 가능한 형태인 느낌인데
일단 만들고 코파일럿과 지피티와 함께 열심히 리팩토링을 진행해야겠다 ^ㅁ^
신기한 걸 발견했다.
여기에 patch_order 의 값을 보면 prev_id 가 int 형인 것을 확인할 수 있는데
def patch(self, request):
"""
- 이 함수는 todo를 수정하는 함수입니다.
- 입력 : todo_id, 수정 내용
- 수정 내용은 content, category, start_date, end_date 중 하나 이상이어야 합니다.
- order 의 경우 아래와 같이 제시된다.
"order" : {
"prev_id" : 1,
"next_id" : 3,
"updated_order" : "0|asdf:"
}
""" # noqa: E501
todo_id = request.data.get("todo_id")
try:
todo = Todo.objects.get(id=todo_id, deleted_at__isnull=True)
except Todo.DoesNotExist:
return Response(
{"error": "Todo not found"}, status=status.HTTP_404_NOT_FOUND
)
if "order" in request.data:
nested_order = request.data.get("order")
request.data["order"] = nested_order.get("updated_order")
request.data["patch_order"] = nested_order
serializer = TodoSerializer(
context={"request": request},
instance=todo,
data=request.data,
partial=True,
)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
이 코드에서 is_valid 함수를 들어가서 validate_ 함수에 들어가니
여기에서 data prev_id 를 보면 또 객체가 되어있다.
근데 일단 오늘은 시간이 너무 늦었으니 내일 찾아봐야겠다.
일단 모든 테스트를 통과한것에 행복함을 느끼기로 했다...
'소프트웨어 마에스트로 > BackEnd(Django)' 카테고리의 다른 글
[백엔드] django sentry log 손보기 + testcode 개편 (0) | 2024.08.23 |
---|---|
[백엔드] pytest testcode 개편 (0) | 2024.08.16 |
[백엔드] ruff 적용 및 테스트 코드 관리 (1) | 2024.08.15 |
[백엔드] serializer validation 추가하기 ( Fat model) (1) | 2024.08.14 |
[백엔드] sentry django 적용기 (0) | 2024.08.12 |