• 티스토리 홈
  • 프로필사진
    조별하
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
조별하
  • 프로필사진
    조별하
    • 분류 전체보기 (124)
      • 1. 공부 (0)
        • 기술 면접 (0)
      • 2. 웹개발 (7)
        • Java (1)
        • IT 정보 (5)
        • Error 모음 (1)
      • 3. 개인관심 (1)
        • 전자 (1)
      • GITHUB (5)
      • IT 기술 면접 (3)
      • COMPUTER (2)
      • TASK (1)
      • LANGUAGES (20)
        • Python (3)
        • Django (6)
        • Java (7)
        • Node (1)
        • Jsp (2)
        • R (1)
      • 데이터과학 (2)
        • 머신러닝 및 딥러닝 (2)
      • DATABASE (5)
        • Oracle (2)
      • ISSUE (10)
        • Django (4)
        • Drf (2)
        • Javascript (1)
        • Git (1)
      • JAVA 교육 (65)
        • Java (3)
        • Jquery (2)
        • Sql (16)
        • Jdbc (1)
        • Db (2)
        • Jsp (9)
        • myWeb (15)
        • Servlet (4)
        • Spring (12)
        • Crawling (0)
        • Hosting (1)
      • 정보처리산업기사 (1)
      • EDUCATION (2)
        • IoT 서비스 (2)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [ISSUE]decorator를 이용한 중복작업 전처리
        2023년 05월 05일
        • 조별하
        • 작성자
        • 2023.05.05.:02

        [22.11.26]

        🍃 중복되며 각 함수의 사전에 처리되는 작업 decorator

        📌 SiteBulkAPIView - 벌크 즐겨찾기, 삭제

        class SiteBulkAPIView(APIView):
            """
            벌크 항목 즐겨찾기, 삭제 api
            """
        
            def get_list(self):
        
                pk_ids: list = self.request.data.get('pk_ids')
                
                return get_list_or_404(Site, id__in=pk_ids)
            
            def validate_ids(self):
        
                pk_ids: list = self.request.data.get('pk_ids')
        
                for id in pk_ids:
                    get_object_or_404(Site,id=id)
        
                return self.get_list()
        
            def put(self, request):
                """
                Site 벌크 즐겨찾기 추가
                """ 
        
                sites = self.validate_ids()
                
                try:
                    with transaction.atomic():
                        '''트랜젝션 시작'''
        
                        for site in sites:
                            site.favorite = self.request.data.get('favorite')
                            site.save()
                except:
                    raise Response({'msg':'Updated failed'}, status=status.HTTP_400_BAD_REQUEST)
        
                return Response({'msg':'Updated successfully'}, status=status.HTTP_200_OK)
        
            def delete(self, request):
                """
                Site 벌크 삭제
                """        
                sites = self.get_list()
        
                for site in sites:
                    site.delete()
            
                return Response({'msg': 'Deleted successfully'}, status=status.HTTP_200_OK)

         

        📌 SiteTagsAPIView - 벌크 태그

        class SiteTagsAPIView(APIView):
            """
            벌크 항목 태그 api
            """
        
            def get_list(self):
        
                pk_ids: list = self.request.data.get('pk_ids')
                
                return get_list_or_404(Site, id__in=pk_ids)
            
        
            def validate_ids(self):
        
                pk_ids: list = self.request.data.get('pk_ids')
        
                for id in pk_ids:
                    get_object_or_404(Site,id=id)
        
                return self.get_list()
            
            def post(self, request, **kwards):
                """
                Site 태그 추가
                """ 
                sites          = validate_ids()
                tags           = self.request.data.get('tags')
        
                with transaction.atomic():
                    '''트랜젝션 시작'''
                    
                    created_tags   = [Tag.objects.create(name=tag) for tag in tags]
        
                    [tag.site.add(site.id) for tag in created_tags for site in sites]
                
                return Response({'msg':'Updated successfully'}, status=status.HTTP_200_OK)

         

        🍃 코드 작성 시 문제점

        ✔️ 벌크 즐겨찾기, 삭제 Class를 코드를 작성한 후, 벌크 태그 Class 코드를 작성하는데 bulk작업이다 보니 데이터를 조회하고 검증하는 작업이 두 Class에서 반복적으로 사용이 됐다.

        def get_list(self):
        
                pk_ids: list = self.request.data.get('pk_ids')
        
                return get_list_or_404(Site, id__in=pk_ids)
        
            def validate_ids(self):
        
                pk_ids: list = self.request.data.get('pk_ids')
        
                for id in pk_ids:
                    get_object_or_404(Site,id=id)
        
                return self.get_list()

        📌 해결방법

        ✔️ 반복되는 데이터 조회와 검증하는 작업을 decorator로 분리를 시키고 각 class의 api함수에서는 반복되는 코드를 줄이는 작업을 진행해보자

        📌 decorator 사용

        def bulk_decorator(func):
        
            @wraps(func)
            def exec_func(self, request) -> func:
        
                pk_ids: list = self.request.data.get('pk_ids')
        
                sites = validate_ids(pk_ids)
        
                return func(self, request, sites=sites)
        
            def get_list(pk_ids: list) -> Site:
        
                return get_list_or_404(Site, id__in=pk_ids)
        
            def validate_ids(pk_ids: list) -> Site:
        
                for id in pk_ids:
                    get_object_or_404(Site,id=id)
        
                return get_list(pk_ids)
        
            return exec_func

        ✔️ bulk_decorator함수

        • 데코레이터 실행 함수 exec_func를 실행할 수 있게 return으로 exec_func를 반환
        • 각 Class에서 작성하던 중복되던 함수 get_list와 validate_ids함수를 bulk_decorator내부 함수로 작성
        • exec_func내부에 pk_ids로 전달받은 pk(id) 배열 값을 validate_ids()함수의 매개변수로 호출하여 sites 변수에 담아 실행함수 return 값으로 전달받은 함수의 키워드 가변인자 값으로 전달해 주게 변경

        ✔️ @bulk_decorator 사용

         

         class SiteTagsAPIView(APIView):
             """
             벌크 항목 태그 api
             """
        
             **@bulk_decorator**
             def post(self, request, **kwards):
                 """
                 Site 태그 추가
                 """ 
                 sites          = **kwards['sites']**
                 tags           = self.request.data.get('tags')
        
                 with transaction.atomic():
                     '''트랜젝션 시작'''
        
                     created_tags   = [Tag.objects.get_or_create(name=tag)[0] for tag in tags]
        
                     [tag.site.add(site.id) for tag in created_tags for site in sites]
        
                 return Response({'msg':'Add tag successfully'}, status=status.HTTP_200_OK)
        class SiteTagsAPIView(APIView):
            """
            벌크 항목 태그 api
            """
        
            @bulk_decorator
            def post(self, request, **kwards):
                """
                Site 태그 추가
                """ 
                sites          = kwards['sites']
                tags           = self.request.data.get('tags')
        
                with transaction.atomic():
                    '''트랜젝션 시작'''
                    
                    created_tags   = [Tag.objects.get_or_create(name=tag)[0] for tag in tags]
        
                    [tag.site.add(site.id) for tag in created_tags for site in sites]
                
                return Response({'msg':'Add tag successfully'}, status=status.HTTP_200_OK)
        ✔️ 반복되며 사용되던 get_list와 validate_ids함수 코드가 분리되어 @bulk_decorator로 사용이 가능해지니 간결화되고 구조화되어 재사용성이 늘어났다.
        저작자표시

        'ISSUE > Django' 카테고리의 다른 글

        [ISSUE] Tag 포함된 Site 모델의 serialize 처리  (0) 2023.05.06
        [ISSUE] ManytoMany 관계를 가진 두 모델 Bulk Create 작업  (1) 2023.05.06
        [ISSUE] signup AbstractBaseUser class  (0) 2023.05.05
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바