TIL. 최종프로젝트(2) 이중구조 json 처리

2023년 06월 07일 by barryjung

    TIL. 최종프로젝트(2) 이중구조 json 처리 목차

[오늘 한일]

  • 서면 피드백 받은 내용 회의
  • 프로젝트 폴더 생성
  • 기능별 개발 진행

 

[오늘 논의한 내용]

  • 아침회의 : 피드백 받은내용
    • 역할 나누기 : 크게 나눌것인가 X. 선제적으로 하게될 역할을 우선 기입함.
    • API 명세서 피드백 받은내용 고치자
    • 문제 유형. 차차 고민해보기로.
    • 주차별 진행목표. 알고있는 내용은 2주차 초까지 완성하자.
    • 진행상황 공유와 기록을 위한 노션 작업 캘린더 생성.
  • 진행하며 의논한부분
    • 프로젝트폴더생성: 마이그래이션파일 공유 유무. 공유X.
    • poetry사용법 공유
    • postgresql을 개발단계에서부터 활용여부 O. 생성단계에선 sqlite3.
    • crawling용 app별도로 두겠다. Ok. selenium으로 진행.
    • python formator로 prettier는 미동작. black으로 변경.
    • .vscode의 공유 유무. 공유X. gitignore에 추가.
    • Achieve 모델에 의의와 연결성 장착설정 논의. > 모델 구조 변경.
    • User모델과 Userinfo 모델에 대한 논의
    • 깃 커밋메세지, 브랜치 작명 작성법. O.

 

[오늘 배운점]

poetry

<poetry 사용법>

poetry를 처음 활용해보게 됬다.

 

poetry 개발환경을 공유 받는 방법은 아래와 같다.

1. poetry를 설치한다. powershell로 설치.

2. vscode로 작업영역을 연다.

3. 터미널에서, 먼저 가상환경을 설치한다. poetry install

4. 가상환경을 활성화 한다. poetry shell

5. 파이썬 파일을 실행해본다. python manage.py runserver

 

명령어가 짧고 간단한 편이다.

 


git

<마이그래이션 폴더와 init은 허용, 나머지는 제외>

장고 migrations파일을 공유하고 싶지 않은데,

migrate에 필요한 폴더와 파일은 공유에서 제외하고 싶지않다면 어떻게 해야할까.

 

**/migrations/*
!**/migrations/__init__.py

여러가지로 비슷하게 시도해본 끝에,

gitignore에 이렇게 작성하면 잘 제외된다.

 

https://stackoverflow.com/questions/59706492/how-to-ignore-migrations-but-init-py 여기서 참고했다.

 


DRF

<시리얼라이저로 한번에 여러 데이터 처리하기>

한번에 요청에 여러개 데이터를 받아야 한다면.

시리얼 라이저에 여러 데이터를 처리 시켜야 한다.

 

(request.data로 해당 데이터들을 뽑아내서,

손수 반복문을 돌리며 한 데이터씩 시리얼라이저>검증>저장을 해도 되긴 하다.

하지만 적절하지 않아 보인다.)

 

여러개의 데이터라면 역시 리스트이다.

처리해야할 json데이터 묶음이 리스트로 들어온다면,

serializer(request.data, many=True)를 주는게 가장 적합하다.

 

 

그런데 이때, 각 데이터 마다 가공이 필요하다면?

오늘 나는 각 데이터 묶음마다 id값을 붙여줄 필요가 있었다.

(해당 id값 또한 같은 요청으로 생성되는 인스턴스의 id이다.)

 

이 문제 때문에 다시 상위의 방법으로 돌아가면 안되겠다.

many=true와 함께 각데이터를 가공할 방법은 뭘까.

나는 kwargs를 이용하여 해결방법을 찾았다.

 

OptionSerializer(data=request.data["options"], many=True, quiz_id=save_quiz.id)

뷰에서 request.data를 가지고 serializer인스턴스를 생성할때를 주목해봤다.

여기에 어떻게든 인자로 실어보내 처리해야한다.

알고보니 many=도 kwargs다.

그리고 그 뒤에 내가 커스텀한 quiz_id=를 부여했다.

 

시리얼라이저 인스턴스가 생성될때 이 kwargs를 언제 까보는지 역으로 올라가봤다.

ModelSerializer > Serializer > BaseSerializer까지 올라간다.

이 BaseSerializer에 인스턴스 초기화 메소드에서 kwargs를 잘라내어 담는다.

 

class OptionSerializer(serializers.ModelSerializer):
    (중략)
    def __init__(self, instance=None, data=..., **kwargs):
        """초기화 메소드

        인스턴스 생성시 함께 생성되는 퀴즈의 id를 지정해야 하기 때문에,
        kwargs에 quiz_id를 받아옵니다.
        init을 오버라이드 해서 데이터에 실어줍니다.

        Args:
            quiz_id : 퀴즈 인스턴스의 id.
        """
        quiz_id = kwargs.pop("quiz_id", None)
        if quiz_id:
            for option in data:
                option["quiz"] = quiz_id
        super().__init__(instance, data, **kwargs)

내가 작성한 시리얼라이저이다.

__init__ 초기화 메소드를 오버라이드해서,

모듈에서 그렇게 하듯이, pop으로 kwargs에서 뽑아낸다.

나머지는 그대로 상위메소드로 보내면서 마무리한다.

 

결론, 이렇게 해서 여러개 데이터를 한번에 처리하며 각 데이터를 가공해 줄수 있었다.

https://stackoverflow.com/questions/42398477/serializing-a-list-of-objects-with-django-rest-framework
https://stackoverflow.com/questions/31278418/django-rest-framework-custom-fields-validation 참고한 내용.

 


<ellipsis 오브젝트?>

위가 가능했던건 init메소드 파라미터중 data에 입력된 data가 그대로(리스트 모양 그대로)

실려왔던 것도 중요하다.

 

반면 모델 인스턴스를 이용해 시리얼라이저 인스턴스를 만들면,

data부분이 print도 안되고 ellipsis라는 데이터 타입으로 보이게 된다.

data 인자를 안실었으니 기대하는 값이 없는 것은 당연하다.

대신 instance부분이 채워져서 들어온다.

 


<이중 구조 json데이터 처리>

어쨌든 오늘 해낸일은 다중구조 데이터의 입출력이다. 입력할때는 options을 구분하고(왼쪽) 출력에서는 options을 퀴즈와 묶은 모습이다(오른쪽).

 

지금으로써는 로직이 간단하지만, 우선 퀴즈를 입력하고 조회하는데,

기본형을 만들었다.

여기서 로직이 더 강화될수 있겠다.

어쨌든, 아주 잘가고 있다.