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

제갈창민·2021년 12월 27일
1

기업협업[퀀텀AI]

목록 보기
1/18

무대가 열렸다, 막이 올랐다 위로 올라가 니 세상을 보여 줘(기대해도 좋아)

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

D

드디어 총 4주, 2번의 프로젝트가 끝나고 기대와 긴장 속에 기업협업이 시작되었다.
우리 27기는 따로 플랜이 있었던 1명을 제외하고 40명 전원이 기업협업에 참여했는데, 나는 프1, 백2 로 이뤄진 3인 팀에 합류하게 되었다.
회사는 퀀텀AI라는 이름의 안면인식 인공지능 기반으로 얻은 데이터의 통계를 가지고 서비스를 하는 곳이었고 위치는 출, 퇴근의 메카 가산디지털단지였다.
퀀텀AI
대표님의 첫 인상은 후리함(free). 그리고 우리에게 하신 첫 마디도 '복장은 자율입니다' 였는데, 입가에 그려지는 미소를 감출수가 없었다. 사실 내게 취직을 할 때 가장 큰 불안요소는 다름 아닌 셔츠, 정장 통일 이었으니까. 그리고 이어서 회사의 현재 프로젝트, 목표, 최근 성과 등등 소소한 것까지 자세하게 알려주셨고, 또 하나 마음에 들었던, '아, 점심은 사드립니다. 옆 건물에 있는 한식뷔페가 있어요.' 이 한마디. 자율 복장에 밥 주고 10시 출근? 나한텐 이미 허들이 없는거나 마찬가지. 그저 대략 너무나 좋았다.

R

알면 알수록 신기한 백엔드의 세계였지만, 사수가 되신 백엔드 개발자님의 설명을 듣는데, 이건 뭐 신세계가 따로 없었다. 아, 먼저 우리에게 하달 된 것들에 대해 먼저 설명해야 하겠다. 프론트는 잘 모르니 패스, 백엔드는 DRF, djangoframework 를 사용하게 되었는데, 공식문서를 보면서 튜토리얼을 따라 하는 것이 첫 날의 임무였다. 물론 점심 먹기 전에 CRUD 를 모두 포함한 간단한 프로젝트를 만드는 것이 먼저긴 했지만, 모델도 간단했고 1, 2차로 다듬어진 model, view 작성법이 남아있어서 그리 어렵지 않게 만들어 낼 수 있었다. 이어서 오후에 DRF를 이용해 오전에 만들어 둔 프로젝트를 리팩토링 했는데, 비슷해 보이면서도 완전히 다른 세상이었다. 그리고 혹시나 이 글을 보게 될 예비 백엔드분들, 꼭 반드시 class 에 대한 개념은 꼭꼭꼭꼭꼭꼭 숙지하길 바란다. 나중에 열어보면 알겠지만, 온통 class의 쓰나미다. 추상화 된 모델에 클래스에 함수에.. model 만들면서 추상화 모델을 한 번 만들어 봤으니 망정이지, 멍 때리다 울면서 돌아올뻔 했다. 암튼, 우리 자비로우신 사수님은 위코드 분이 셨는데, 마치 1타 강사처럼 세세하게 조목조목 알려주시면서 집중공부해야 할 부분, 나중에 해도 될 부분 등을 나눠서 알려주셨다. 진짜 사수님 짱!

F

프론트쪽 사수님도 굉장히 친절하시고 마치 동기에게 알려주듯이 연신 괜찮다면서 자세하게 설명해주려고 애를 쓰시는게 보였다. 본인들의 업무만으로도 야근을 해야 할 판인데, 한 달 후에 떠나게 될 우리에게 시간을 소비하시면서도 티도 내지 않으시고 질문은 언제든 하라시는 모습이 너무나 감사했다. To do list 가 쌓여 있는 와중에 나는 과연 저렇게 할 수 있을까 하고 다시 생각해보게 만드는 첫 날 이었다. 그래서, 첫 날의 만족도? 당연한 것 아닌가, 무조건 100점 만점.

TIL

우선 선생님, 학생으로 이뤄진 모델로 간단한 CRUD를 구현했다.

views.py
class TeacherView(View):
    def get(self, request):
        teachers = Teacher.objects.all()
        
        result = [{'name' : [teacher_data.name]}for teacher_data in teachers]
        return JsonResponse({'result':result}, status=200)
        
    def post(self, request):
        data = json.loads(request.body)
        
        Teacher.objects.create(
            name = data['name']
        )
        return JsonResponse({'message' : 'Created'}, status=201)
        
    def patch(self, request):
        data = json.loads(request.body)
        teacher = Teacher.objects.get(id=data['id'])
        teacher.name = data['new_name']
        teacher.save()
        
        return JsonResponse({'message' : 'Success'}, status=200)
    
    def delete(self, request):
        teacher_id = request.GET.get('id')
        Teacher.objects.filter(id=teacher_id).delete()
        
        return JsonResponse({'message' : 'Delete Success'}, status=200)
    
class StudentView(View):
    def get(self, request):
        students = Student.objects.all()
        
        result = [
            {
                'teacher' : student_data.teacher.name,
                'name'    : student_data.name,
                'email'   : student_data.email
                } for student_data in students
            ]
        
        return JsonResponse({'result':result}, status=200)

    def post(self, request):
        data         = json.loads(request.body)
        teacher_data = data['teacher_data']
        
        teacher_id = Teacher.objects.get(id=teacher_data)
        
        Student.objects.create(
            name       = data['name'],
            email      = data['email'],
            teacher_id = teacher_id.id
        )
        return JsonResponse({'message' : 'Created'}, status=201)
        
    def patch(self, request):
        data = json.loads(request.body)
        student = Student.objects.get(id=data['id'])
        
        student.name = data['new_name']
        student.email = data['new_email']
        student.save()
        
        return JsonResponse({'message' : 'Success'}, status=200)
    
    def delete(self, request):
        student_id = request.GET.get('id')
        Student.objects.filter(id=student_id).delete()
        
        return JsonResponse({'message' : 'Delete Success'}, status=200)

patch 부분에 기능상 문제가 있지만, 일단 넘어가도록 하자.
아래는 Djangoframework 의 serializer 를 이용한 리팩토링 코드이다.

views.py
class TeacherModelViewSet(viewsets.ModelViewSet):  # 클래스명은 룰임
    permission_classes = [AllowAny] # 누구나 접근 가능(디폴트)
    serializer_class = TeacherSerializer
    queryset = Teacher.objects.all()
    
class StudentModelViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = StudentSerializer
    queryset = Student.objects.all()
    
class ScoreModelViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = ScoreSerializer
    queryset = Score.objects.all()

이것만 보면 도저히 알 수가 없다. 그래서 아래와 같은 것들이 선행되어야 한다.

serializers.py
from .models    import Score, Teacher, Student
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer

class TeacherSerializer(ModelSerializer):
    student_name = serializers.SerializerMethodField()
    
    class Meta:
        model = Teacher
        fields = '__all__'
        
    def get_student_name(self, data):
        student = data.student_set.all()
        return student.values()
    
class StudentSerializer(ModelSerializer):
    teacher_name = serializers.SerializerMethodField()
    score_total = serializers.SerializerMethodField()

    class Meta:
        model = Student
        fields = '__all__'
        
    def get_teacher_name(self, data):
        return data.teacher.name

    def get_score_total(self, data):
        score = data.score_set.get()
        total = score.korean + score.english + score.math

        result = {
            'total' : total,
            'avg' : total/3
        }
        return result

class ScoreSerializer(ModelSerializer):

    class Meta:
        model = Score
        fields = '__all__'

urls.py
from django.urls  import path
from user.views import StudentModelViewSet, TeacherModelViewSet, ScoreModelViewSet

teacher_list = TeacherModelViewSet.as_view({
    'get'  : 'list',
    'post' : 'create'
})

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

student_list = StudentModelViewSet.as_view({
    'get'  : 'list',
    'post' : 'create'
})

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

score_list = ScoreModelViewSet.as_view({
    'get'  : 'list',
    'post' : 'create'
})

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

urlpatterns = [
    path('teacher/', teacher_list),
    path('teacher/<int:pk>/', teacher_detail),
    path('students/', student_list),
    path('student/<int:pk>/', student_detail),
    path('score/', score_list),
    path('score/<int:pk>/', score_detail),
]

serializers.py 에 잔뜩 들어있는 serialize 가 오늘 학습의 핵심이다. 사수님의 설명에 의하면, ModelView 사이에 있는 추상 클래스와 그보다 더 추상화 된 함수로 이루어진 코드다. 그래, 사실 아직은 잘 모르겠다. 공식문서에서 튜토리얼부터 정독해봐야 할 듯하다.
이제 시작이다 싶었더니, 아직도 신발끈을 묶고 있는 중이었다.

인생은 나의 무대, Attention Everybody.

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

profile
자기계발 중인 신입 개발자

0개의 댓글