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

제갈창민·2021년 12월 29일
0

기업협업[퀀텀AI]

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

백번 넘어져도 백 한번째 일어나, 그 누가 뭐래도 한길로 끝까지 걸어가

[ 클로버, La Vida Loca 중에서 ]

D

드디어 오늘 첫 과제를 받았다. 사수분이 직접 회사의 코드에 기반해 모델링을 해주셨고, 연습용이기에 단 4개의 테이블과 각각 1,2개씩의 필드로 구성되었다.

  • Category(한식, 중식 등), Shop(식당 명), Customer(손님), Visited(방문 했던 손님)

필드는 name 과 visited_time(방문시각) 으로만 구성되었고, 세 가지 기능을 DRF로 구현해보라고 하셨다.

  • category 검색했을 때 해당 카테고리 매장 리스트,
  • Shop 검색했을때 해당 매장 총 방문객(total) + 방문객 리스트 (이름)
  • account 검색했을때 내가 방문한 매장 - 언제 방문했는지

R

RESTful API 때도 그랬지만, 개발자들은 REST를 정말 좋아하는 것 같다. framework 인 Django 에서조차 REST를 적용할 줄이야. 온라인 강의와 공식문서를 병행하면서 점점 DRF에 빠져들고 있긴 하지만, 알면 알수록 점점 축약되고 줄어드는 코드가 신기하면서도 '이렇게까지 함축해도 되나?' 싶을 정도로 추상적이어지는데, 세상에서 가장 힘든게 남의 코드 보는 거다라는 말이 다시 한번 체감하는 순간이었다. DRF를 모르는 개발자가 와서 본다면 '이게 뭔데?' 라고 할 만큼 꽁꽁 숨겨뒀으니 말이다. 하지만 또 그만큼 코드가 깔끔해지고 함축했음에도 확장성이나 튜닝이 수월하게끔 만든 부분도 있으니, 만든 분들은 진심 천재이지 않은가. 감탄은 여기까지하고, 다시 코드로 돌아가 보겠다.

F

ForeignKey의 관계는, Shop 이 Category의 pk를, Visited 가 Shop과 Customer의 pk를 가진 관계였다. 두 달간 익숙해진 def get, def post를 버리고 완전한 DRF 의 형식으로 쓰려니 쉽게 타자가 쳐지지 않았다. 최대한 자료들을 참조하지 않고 기억이 나는 것까지 작성해보려 했으나, 일부분만 기억이 날 뿐, 결국 공식문서를 참조해서 겨우 시작할 수 있었다. <코드는 아래쪽 TIL에서>

TIL

serializers.py
class CategorySerializer(ModelSerializer):
    class Meta:
        model = Category
        fields = '__all__'

class ShopSerializer(ModelSerializer):
    class Meta:
        model = Shop
        fields = '__all__'
    
class CustomerSerializer(ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'

class VisitedSerializer(ModelSerializer):
    class Meta:
        model = Visited
        fields = '__all__'
        
views.py
class CategoryModelViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny] 
    serializer_class = CategorySerializer
    queryset = Category.objects.all()
    
class ShopModelViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny] 
    serializer_class = ShopSerializer
    queryset = Shop.objects.all()

class CustomerModelViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny] 
    serializer_class = CustomerSerializer
    queryset = Customer.objects.all()

class VisitedModelViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny] 
    serializer_class = VisitedSerializer
    queryset = Visited.objects.all()

먼저 serializer.py 를 작성해야 views.py도 작성할 수 있다. 아직 ViewSet에 대한 학습이 많이 되진 않았지만, 사수 분이 일단 써보면 감이 온다고 하셔서 닥돌하기로 마음먹고 써내려 갔다. 여기까지하고 runserver 를 해봤는데, urls.py를 빼먹었다. 처음엔 기존에 urls.py를 작성하던대로 --ModelViewSet들을 .as_view()로 이어줬었다.

urlpatterns = [path('category', CategoryModelViewSet.as_view()),]

그랬더니, [{'get', 'list'}] 가 빠졌다면서 에러를 출력했다. 공식문서를 다시 살펴보고 다른점을 확인했더니, urls.py의 모양이 아래와 같이 완전히 변해있었다.

category_list = CategoryModelViewSet.as_view({
    'get' : 'list',
    'post' : 'create',
})

category_detail = CategoryModelViewSet.as_view({
    'get' : 'retrieve',
    'put' : 'update',
    'patch' : 'partial_update',
    'delete' : 'destroy'
})

shop_list = ShopModelViewSet.as_view({
    'get' : 'list',
    'post' : 'create'
})

shop_detail = ShopModelViewSet.as_view({
    'get' : 'retrieve',
    'put' : 'update',
    'patch' : 'partial_update',
    'delete' : 'destroy'
})

customer_list = CustomerModelViewSet.as_view({
    'get' : 'list',
    'post' : 'create'
})

customer_detail = CustomerModelViewSet.as_view({
    'get' : 'retrieve',
    'put' : 'update',
    'patch' : 'partial_update',
    'delete' : 'destroy'
})

visited_list = VisitedModelViewSet.as_view({
    'get' : 'list',
    'post' : 'create'
})

visited_detail = VisitedModelViewSet.as_view({
    'get' : 'retrieve',
    'put' : 'update',
    'patch' : 'partial_update',
    'delete' : 'destroy'
})

urlpatterns = [
    path('category', category_list),
    path('category/<int:pk>', category_detail),
    path('shop', shop_list),
    path('shop/<int:pk>', shop_detail),
    path('customer', customer_list),
    path('customer/<int:pk>', customer_detail),
    path('visited', visited_list),
    path('visited/<int:pk>', visited_detail),
]

조언에 따르면, serializerviewset의 능력으로 이곳에서 CRUD 를 모두 처리해 주는 것이라 했다. 하지만 실제 현업에서는 views.py에서 확실하게 하나하나 지정해서 다시 작성해준다고 하셨다.
여기까지 했는데 시간이 6시를 넘어서고 있었다. 재빨리 과제를 위한 코드를 구현하기 시작했으나, 다 끝내지 못하고 첫 번째 과제만 완성하였다.

class CategorySerializer(ModelSerializer):
    shop_name = serializers.SerializerMethodField()

    class Meta:
        model = Category
        fields = '__all__'

    def get_shop_name(self, data):
        shop = data.shop_set.all()
        return shop.values()

간단한(?) 역참조 관계의 데이터를 불러오는 코드이다. pk를 갖고 있는 shop 테이블에서 _set.all() 로 데이터를 가져온 뒤, .values() 로 데이터를 출력한다. .values() 괄호 안에 특정 필드값을 지정해서 해당 값 들만 출력할 수도 있다.
퇴근 후 집에서 두 번째 과제를 해보려 했지만, 실패했고 내일의 나에게 맡기기로 한다.

뜨거운 조명 아래 거기가 내 자리요, 뜨겁게 놀다 갈래 put your hands in the air yo~

[ 클로버, La Vida Loca 중에서 ]

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

0개의 댓글