[기업협업] 퀀텀AI -Day 9-

제갈창민·2022년 1월 4일
0

기업협업[퀀텀AI]

목록 보기
6/18
post-custom-banner

창의력은 완전 제로 난 곧이 곧대로 1은1인 내 머리에 예술성은 없어

[ 배치기, "마이동풍" ]

D

동파방지 뉴스기사를 읽으면서 월요일 출근을 하는데, 생각보다 이번 겨울은 안춥다는 생각이 들었다. 부산도 아니고 서울인데.. 아직 1월 초라 그런가. 아무튼, 오늘은 본격적으로 회사 프로젝트를 시작하는 날이다. 저번주에 사수님이 미리 말씀하셨듯, 현재 개발하고 있는 서비스에서 admin 과 user 페이지를 다루게 될 예정이었는데, 아침 스크럼(매일 아침 10~15분정도 진행한다)에서 이 부분이 살짝 조정되었다. User 페이지는 API가 거의 완성되어있어서 버그수정이나 리팩토링이 목적이었고, admin 페이지는 처음부터 만들어나가야 했는데, User를 담당하게 되면 코드를 살펴보는데에만 1~2주가 소요 될 것이고, 또한 자잘하게 준비해야 할 것도 많기에, 이제 3주밖에 남지 않은 우리가 하기에는 별로 도움 될 것이 없다고 설명하시면서 결과적으로 admin 페이지에 둘 다 투입 될 것이라고 알려주셨다.

R

리팩토링도 하고 싶었지만, DRF를 처음 배우는 입장이라서 기초부터 하나하나 만들어 가보고 싶어서 처음부터 admin 을 하기로 했었던 나에게는 달라진 것은 없었다. 스크럼이 끝나고 뒤이어 기능별 업무분담이 이뤄졌다. 내가 맡은 부분은(회사의 프로젝트 정보가 노출 될 수 있으므로 최대한 두루뭉술하게 작성함)매장의 리스트를 필요한 필드의 데이터만 가져와서 뿌려주면 되는, CRUD에 기반한 기능 구현이었다. 코드는 맨 아래쪽에 따로 기술하겠다.

F

(First)먼저 각 app의 Model 을 살펴보았는데, 진짜 종류가 많았다. 모델만 다 살펴보려고 해도 3,4일은 걸려보였다. 그래서 모두 살펴보는건 재빨리 드랍하고 내가 구현해야하는 매장에 대한 모델과 필요한 필드 및 데이터들이 있는 모델만 빠르게 캐치해서 파악하기로 했다. 가져와야하는 데이터 중 3가지가 다른 앱의 모델에 있었고, 테이블 간 관계도 정, 역참조, ManytoMany 까지 다 섞여있었다. git clone 을 받고 branch 를 생성한 뒤 작업을 시작했다.

TIL

views.py
class SchoolListViewSet(ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = SchoolListSerializer
    queryset = School.objects.all()
(회사 정보 보호를 위해 최소한의 코드만 쓰고 내용도 변경하였음)
-------------------------------------------------------------
serializers.py
class SchoolListSerializer(serializers.ModelSerializer):
      school_image = serializers.SerializerMethodField()
      school_desk = serializers.SerializerMethodField()
    
    class Meta:
          model = School
          fields = ['id', 'school_name', (etc)]

    def get_school_image(self, obj):
        return obj.schoolimage_set.all().values('school_img')

(회사 정보 보호를 위해 최소한의 코드만 쓰고 내용도 변경하였음)
---------------------------------------------------------------
urls.py
router = DefaultRouter()
router.register(r"school", SchoolListViewSet, basename="school")
school_list = SchoolListViewSet.as_view({
    'get': 'list',
    'post': 'create'
})

urlpatterns = [
               path('admin-school/', school_list)
	      ] + router.urls
(회사 정보 보호를 위해 최소한의 코드만 쓰고 내용도 변경하였음)

매우 간단히 작성한 ClassBasedView (CBV)와 serializer이다. DRF는 공식문서가 지이인짜로 친절하고 자세하게 설명되어있다. 심지어 튜토리얼도 알차게 구성되어 있어서 다른 무엇보다도 DRF를 시작할 땐 꼭 공식문서를 정독하길 추천한다.
DjangoRestFramework 공식홈페이지
그동안 학습한것을 토대로 하나하나 설명해보겠다.

views.py

class(ModelViewSet)

DRF는 다양한 ViewSet을 제공하는데, 기본이 되는 ViewSet 부터 GenericViewSet, ModelViewSet이 주로 사용되고, 이외에도 ReadOnlyModelViewSet 이 있고, 필요한 기능만 Mixin하여 사용 할 수 있는 Custom ViewSet도 있다. 그 중 범용성이 가장 크고 다른 모든 ViewSet들의 기능을 모두 가지고 있는 ModelViewSet을 사용한 것이다.

permission_classes = [AllowAny]

DRF에서는 API, 즉 View 마다 접근 권한을 부여 할 수 있다. settings.py에 Default 값을 설정 할 수 있으며, 아무것도 지정하지 않으면 기본값은 AllowAny 이다. 자주 사용되는 것 중에는 인증을 통과한, 즉 인증된 token을 소유한 유저만 접근 할 수 있는 IsAuthenticated, 관리자만 접근 할 수 있는 IsAdminUser 가 있고, ModelPermissionModelObjectPermission처럼 Custom하거나 특정 기능에 대한 권한만 통제 할 수 있는 방법도 있다.

serializer_class = SchoolListSerializer

해당 ModelViewSet과 연결되어 있는 Serializer class를 지정해 준다. 제대로 지정해주지 않으면, serializer_class를 지정하거나, def get_serializer함수를 통해 overriding하라는 에러가 출력된다. ModelViewSet은 그냥 serializer_class를 지정해주면 끝이지만, 다른 ViewSet들은 get_serializer와 같은 추가 함수를 작성해서 지정해 주어야 한다.

queryset = School.objects.all()

View에서 추가적인 연산이 없다면, 해당 queryset에서 불러온 데이터가 serializer로 전달 된다. View class 아래에 추가 함수를 작성해서 .filter(), get()등등의 다른 연산을 한 후 데이터를 전달하는 방법도 당연히 가능하다.

serializers.py

school_image = serializers.SerializerMethodField()

serializer에는 Model에서 처럼 여러가지 다양한 fields를 사용 할 수 있는데, 이번에 사용한 SerializerMethodFieldCustom Field를 제외한 대부분의 field속성을 모두 포함하고 있다.

model = School

Models.py에서 정의해둔 Model중 사용하고자 하는 것을 가져다 쓰면 된다.

fields = ['id', 'school_name', (etc)]

지정된 Model에서 출력하고자 하는 field를 따로 지정 할 수도 있고, '__all__'을 사용해서 field를 전부 출력 할 수도 있지만, 통상적으로는 필드를 지정해서 사용한다. 추가적인 연산을 통해 해당 모델에 없는 필드도 추가해서 사용 할 수 있다.

urls.py

router = DefaultRouter()

API가 많아지다 보면 당연히 Endpoint 역할인 path 도 많아 지기 마련이다. 이러한 불편함을 해소하고자 개발된 routerViewSet만 등록하면 Path ParameterQuery Parameter든 구분없이 수용 할 수 있어서 굉장히 효율적이고 편리한 기능중 하나이다.

urlpatterns = [ path('admin-school/', school_list)] + router.urls

회사의 정책이나, 선임 사수의 컨벤션 등에 따라, url을 좀 더 정확하고 명확하게 지정 할 수도 있는데, school_list가 추가로 지정된 값의 변수명인 셈이다. 굳이 이렇게 쓰지 않아도 기능상의 문제는 없다.

운명 속 내 별도 떨어져 날 내쳐도 그 고난 속에서도 음 하하하하

[ 배치기, "마이동풍" }

profile
자기계발 중인 신입 개발자
post-custom-banner

0개의 댓글