Internship - saladlab

심준보·2023년 10월 20일
0
post-thumbnail

좋은 기회로 , 이커머스 시장에서 업체 그리고 소비자에게 만족감을 주는 서비스를 개발하는 회사 "샐러드랩" 에 4달간의 인턴기회를 얻게 되었다.
평소 트렌드에 민감하고 패션,가구등에 관심이 많았기에 이와 관련된 분야의 서비스를 개발하는 회사에서 일을 하고 싶다는 생각을 하였고 이것이 현실이 되었다.
그럼 지금부터 인턴십에 대한 이야기를 해보고자한다.

1. "cafe 24 알파리뷰 모듈 설치"

2. "알파리뷰 메일 서비스 구현"

3. "샐러드랩 온보딩 과정 수행"

현재 10/20 일 시점으로 , 인턴을 시작한지 7주차이다.
이 시점에서 크게 위 3가지 항목에 대해 개발이야기를 할 수 있을거라고 생각된다.


먼저, 가장 인상깊었던

3. "샐러드랩 온보딩 과정 수행" 에 대한 이야기로 시작하겠다.

기존의 인턴분들, 새로운 개발 신입 분들은 모듈 설치를 학습 한뒤 , 온보딩 과제를 수행하며 "샐러드랩"의 앞으로의 개발 업무를 원활히 수행하기 위한 과정을 다졌다고 한다.
하지만, 운이 좋게(?) 온보딩 과제를 수행하기 전 인턴분이 할만한 테스크가 주어졌다고 하여 , 알파리뷰 서비스를 사용하기로 한 업체에게 보내는 "메일 서비스"를 구현해보는 기회를 가지게 되었다. 이 부분에 대해서는 나중에 여유가 생기면 차근차근 다루기로 하겠다.

메일 서비스를 구현하고 배포가 된 이후 , 본격적인 "샐러드랩 온보딩 과정" 을 수행해보게 되었다.
먼저, 인턴십을 하기 전 백엔드에 대한 무서움, 나와는 거리가 먼 것이라는 생각을 가지고 있었고 프론트엔드는 공모전 및 프로젝트를 진행할떄 맡아보면서 그래도 친밀감이 있는 분야였다.

"온보딩 과정" 은 Todo list 구현인데 , 프론트엔드 그리고 백엔드까지 전체적인 웹 개발을 해야하는 것이었다. TODDLIST 라는 것이 예전에 react에 입문을 하려고 했을때나 어떠한 것을 보더라도 구글에 예시로 많이 언급되는 분야인만큼 친밀감이 있었고 , 어렵게(?) 느껴지지는 않았다.
하지만, 그러한 생각은 오만이었고 개발을 잘 몰랐기에 할 수 있었던 생각이라고 말할 수 있겠다.

saladlab - todolist onboarding

- django

- Angular

현재 인턴으로 배정된 개발팀에서 서비스하고 있는 "국내 알파리뷰"는 django , angular 를 사용하여 웹개발을 한다. 그렇기에 이번 온보딩 과정에서 사용한 프레임워크는 장고와 앵귤러였다.

"장고" , "앵귤러"

장고는 백엔드에서 java/spring이 있다면 python/django 도 존재한다란 식으로 얼추 알고 있었으며 간단하게 사용해보았었다.

앵귤러는 정말 생소했고 생소했다.

그럼, 이러한 내가 온보딩 과정을 어떻게 진행하였고 해쳐나가보았는지에 대해서 자세하게 다뤄보고자 한다.

<항해 1 일차>

먼저, "샐러드랩" 에서 신입분들 그리고 인턴분들이 온보딩 과정을 수행하는 첫 시작이 원활하도록 아주 기본적인 파일이 구성된 폴더를 깃허브로 올려놓아 주셨다.

그렇기에 git에서 clone을 진행하여 로컬로 폴더를 가져와주었다.

1. 시작 전 clone 수행

git clone url,
git branch myname
git checkout myname
git pull origin main (*기존것 당겨오기)

django

2. 서버 가동 확인하기

#1. 가상환경 구축

python -m venv 가상환경이름
cd scrpits
activate (*가상환경 실행)

#2. 서버 가동 및 확인

python manage.py runserver

#3. 기능 및 역할

  1. urls.py
  • 통신을 위한 url 관리
from django.urls import include, path

urlpatterns = [
    path('api/', include([
        path('todo/', include('todo.urls')),
        path('admin/', admin.site.urls),
        path('user/', include('user.urls') )
    
    ])),
]

상위 root로 api/
그 아래로 admin/ , todo/ , user/ 가 위치하고 있다

admin/
1. 장고의 자동관리 인터페이스
2.이번 온보딩에서는 크게 쓰임이 없다

todo/
1. todo에 관련된 tododb,todoviews를 관리하는곳
2. 가장 많은 동작이 이루어지는 곳이라고 해도 될것같다 .
#개발하는 웹이 todo웹이다 보니

user/
1. 사용자를 관리해줘야 하는 웹이다 보니 로그인,회원가입의 동작을
처리해주는 곳


먼저 , 로그인 및 회원가입 기능을 수행하기 위해 이를 관리할 수 있는 user폴더를 생성한다.
python manage.py startapp user (*django 내에서 user폴더를 생성하기 위한)

user

  • apps.py
  • urls.py

    user/ 아래로 필요한 url들을 저장시켜놓는 곳

  • views.py

    로그인 및 회원가입을 위한 로직이 구현되는 곳

  • models.py

    user model이 명시되는 곳

장고에서는 로그인을 관리해주는 기능을 제공해준다고 한다.
하지만, 이렇게 하지않고 전통적인 방법으로 로그인, 회원가입을 구현하는 것을 목표로 한다.

user

  1. user를 관리할 수 있는 모델을 구축하기
  2. db - sqlite 이용
  3. 모델 구축 및 data가 잘 기입됬는지 확인하기
  4. settings.py - installed_app 에 폴더 명 기입

user.1 - model 구축

user model 명세서

id: int
user_name: str
password: str
created_at : datetime

user.2 - sqlite 이용

sqlite 를 사용하여 이번 웹개발의 데이터를 관리할 것이다

  1. sqlite 알맞은 버전 다운로드
  2. manage.py 와 동일한 레벨의 경로에 설치
  3. settings.py - DATABASES
    DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.sqlite3',
          'NAME': BASE_DIR / 'db.sqlite3',
      }
    }

user.3 - 모델 구축 및 data가 잘 기입됬는지 확인

migrate 사용

  1. python manage.py makemigrations
  2. python manage.py migrate (* 위 명령어까지 해야 제대로 작동이 된다)
  3. python manage.py dbshell (* sqlite 실행 )
  4. .table / .schema / select from table명 (모델이 잘 구축됬는지 확인)

user.4 - settings.py

settings.py에 기입하는 것들이 정말 중요하다고 느낀다.

INSTALLED_APPS = [
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
  'user',
  'todo',
]

위와 같이 , user , todo 의 폴더명을 기입해준다.

이렇게 , user와 관련된 로그인 & 회원가입 로직을 짜기 위한 전반적인 환경을 잡아보았다.

1일차 끝 !

간략한 소감 :

온보딩을 시작하기 전 , django 튜토리얼을 보며 urls.py, views.py , models.py 가 하는 것이 무엇인지에 대해 공부를 해보았었는데 그떄 이해했던것과 직접 하나하나 코드를 적어보며 어떻게 작동하는건지 알아보고 , 선임님의 설명까지 겸하니 앞으로 이 친구들이 어떤 역할을 하는 친구들인지에 대해서 더 와닿았던 것 같다.

<항해 2 일차>

이 날은 백엔드와 프론트엔드간 통신 할 수 있는 기반을 만드는 작업을 하였다.
기존에 react를 사용해서 프론트엔드 작업을 하였을때나 해커톤에 참여했을때도 항상 백엔드와 '통신'하는 부분이 어려웠고 막혔던 경험이 있었다.
그렇기에 이번에는 꼭 나의 힘으로 이를 극복해서 자신감을 얻고 싶었다.

1. 먼저, 프로젝트의 가장 첫 시작인 회원가입 api를 구축해보자

  • 간단한 회원가입 화면 구성 - html
  • db에 임의의 데이터 삽입 - 회원가입절차를 위해
  • 이후 통신 작업

#1. db에 임의의 데이터 삽입

이떄, 임의로 데이터를 삽입해야 했기에 , user_model에서 created_at 필드 속성을 DatetimeField 에서 DateField으로 변경했다.

SQL문 사용

INSERT INTO user_user VALUES ('1' , 'JUNBO' , '1234' ,'2023-09-05')

이렇게 몇개의 데이터를 삽입해놓는다.

#2. 간단한 회원가입 화면 구성 - html

이를 위해, Angular 환경을 셋팅해줘야 한다.

# onboarding/front 경로에 설치
1.  
npm install --save--dev @angular-devkit/build-angular
2.
ng serve
  • 기존의 , clone된 폴더 안에는 기본적인 요소만 있었고, login,signup등을 다뤄주는 component는 존재하지 않았다.
    이를 위해 새롭게 구축을 해야한다.
    여기서 구축 하기전, 어떠한 페이지들이 필요할지 혼자 생각해보았다.
    조금 더 프론트적인 요소에서 괜찮아보이고 싶어 프로토타입에 없던 'home'이라는 시작페이지부터 구상을 시작했다.

#. 부끄럽지만, 이거 한장은 첨부하고 싶었다. (끄적인 흔적)

이런식으로 구상을 하는 시간을 가지고, 유명한 todo web ,instagram등을 참고하며 디자인을 해보았다.

  1. 추가된 'home'

css

  • cursor
  • animation: heart-beat

 .saladlab {
    font-weight: 600;
    animation: heart-beat 1s ease-in-out infinite;
    cursor: pointer;
  }
   
   @keyframes heart-beat {
    0% {
      transform: scale(1);
    }
    25% {
      transform: scale(1.02);
    }
    50% {
      transform: scale(1);
    }
    75% {
      transform: scale(1);
    }
    100% {
      transform: scale(1);
    }
  }

- signup component 생성

ng generate component signup(이름)
  • 회원가입 페이지를 구축하기 위해

      1. home 에서 signup으로 이동되게 routing
      1. signup - html 구축
      1. 함수 생성
      1. django와 통신 확인하기

#1. Routing 을 위해

  • app-routing.modules.ts
import { HomeComponent } from './home/home.component';
import { SignupComponent } from './signup/signup.component';
   

const routes: Routes = [
  { path: 'todo', component: TodoComponent },
  { path: 'home', component: HomeComponent },
  { path: 'signup', component: SignupComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
  • home.component.ts
import { Router } from '@angular/router';
   
export class HomeComponent implements OnInit {
  constructor(private router: Router) {}

  signup() {
    this.router.navigate(['/signup']);
  }
  • home.component.html
<a (click)="signup()" style="color:blue; font-weight: bolder; cursor: pointer;">가입하기</a>

#2. signup - html 구축

  • signup 페이지

여기서, 작업도중 css적인 요소로 마진에서 margin : top,right,bottom,left ; 순이라는 것을 알게되었다.

3. 통신을 위해

  1. input 태그에 있는 username과 password를 간직하고 있어야한다.
  2. 그 값을 서버에 보내준다.
  • 이를 위해, ngmodel을 태그에서 사용한뒤, 프론트가 값을 잘 간직하고 있는지 console.log사용해서 확인을 해보고,
 <input class="inputusername" type="text" [(ngModel)]="username" placeholder="사용할 이름" />
 <input class="inputpassword" type="text" [(ngModel)]="password" placeholder="사용할 비밀번호">
   
  • username, password - ngmodel에 의해 입력된 값이 지정될 변수
export class SignupComponent implements OnInit {
  username = '';
  password = '';
  • console로 데이터 잘 받는지 확인
 // 데이터 잘 받는지 확인하는 작업
  SignupInputText() {
    console.log('username :', this.username);
    console.log('password :', this.password);
  }

이렇게 하여 프론트에서 기입된 값이 변수에 잘 저장된 것을 확인 할 수 있었다.

더 나아가기에 앞서 , angular의 기본 이해가 필요하다 싶어 선배님에게 angular의 정석같은 설명을 듣고 angular를 이해하는데 큰 도움이 되었다.,

#. angular 설명정리

  • angular
    • 컴포넌트간에 데이터 공유 방법
    • service , module, component 의 역할
      • 컴포넌트간에 데이터 공유 방법
        • input,outpu 데코레이터 사용
      • service,module,component?
        • module : 비슷한 기능별로 component를 정리할 수 있는 폴더같은 역할
        • component: module안에 들어있는 component끼리는 같은 service를 사용할 수 있다.
        • service는 어떠한 데서든 사용할 수 있다.
          • 하지만 변수는 공유가 안된다. 같은 모듈안에 있어야만 공유가능

2일차 끝 !

간략한 소감 :

앞에도 말했다 싶이 '통신'에 대해 뭔지 모를 두려움이 컸다 . 하지만 , 오늘 이를 성공하는 과정이었지만 과정속에서 스스로 이해하고 그동안 건너뛰었던게 많았다는 점을 알게되었다. 추가로, 이해를 잘 하면 할 수록 개발이 재미있어진다는 점을 느꼈다. 대충 넘기는 것은 재미도 대충일수 밖에 없다는 생각! 기대가 되었다, 서버에 프론트의 값이 들어가는 것이!

<항해 3 일차>

이날은 서버에 프론트가 던져준 데이터가 잘 들어가게끔 성공시키는 과정과 , 회원가입 로직을 구현하는 목표를 잡았다.

1. 통신 과정

  • Angular
    • apiservice를 이용하여 , create메소드 사용
    • 이떄 , angular 의 통신코드 -> subscribe() , error()
PostInputText() {
    this.ApiServices.create<any>('user/signup', {
      username: this.username,
      password: this.password,
    }).subscribe(
      (json) => {
        console.log('result: ', json);
        this.SignupResult = json['result'];

        if (this.SignupResult == '0') {
          console.log('back값 확인', this.SignupResult);
          alert('회원가입이 완료되었습니다. 감사합니다.');
          this.gologin();
        } else if (this.SignupResult == '1') {
          alert('이미 사용중인 아이디입니다.');
        } else if (this.SignupResult == '2') {
          alert('빈 값을 채워주세요');
        } else console.log('미상 에러');

        // 값 저장하기 (회원가입 여부 성공 or 실패)
      },
      (error) => {
        console.log('error');
        console.log(this.username);
      }
    );
  }
  • 서버로부터 응답이 오면 , subscribe() 내의 동작이 구동
  • 서버로부터 응답이 없다면 , error() 내의 동작 구동
PostInputText() {
    this.ApiServices.create<any>('user/signup', {
      username: this.username,
      password: this.password,
    }).subscribe(
  • username , password 는 서버에게 던져줄 프론트의 값이다.

  • 이는, body에 담겨져 있으며, ['username'] ,['password'] 를 이용하여
    서버에서 사용할 수 있다.



# 통신과정 중 에러 발생

1. cors 에러

해결을 위해,

  • cors를 설치해주고
  • settings.py (django) 에 적용시켜주었다
  
INSTALLED_APPS = [
      'corsheaders',
.
.
.
]
   
CORS_ORIGIN_WHITELIST = ['http://127.0.0.1:4200' ,'http://localhost:4200']

# CORS_ALLOW_CREDENTIALS는 옵션

CORS_ALLOW_CREDENTIALS = True

2. csrf 에러

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    
]
  • 기본값으로 되어있는 csrf 적용 구문을 주석처리를 해주어서 허용을 시켜주어야 통신이 가능해진다.
    • 추가로 , 맨위의 corsMiddleware 구문도 적어주어야 하며 , 이것은 cors오류를 해결하기 위한 방법중 하나이다.

3. '/' 불일치 에러

  • DJANGO와 ANGULAR는 URL에 대한 규약이 다르다.
    • DJANGO는 끝에 자동적으로 '/'을 붙여주고,
    • ANGULAR는 그렇지 않다.
  • 그렇기에 , settings.py에 코드를 추가시켜준다.
APPEND_SLASH=False

이를 통해, 문제를 해결할 수 있다.

3일차 끝 !

간략한 소감 :

예상치 못한 에러사항을 해결하느라 금일의 목표에는 미치지 못하였으나, 이러한 과정속에서, 보안을 위해 다른 포트의 접근을 막아주는 기본 설정값에 대해서도 알게되었고 그 외에도 부가적이지만 앞으로 꼭 필요한 요소들을 알아갈 수 있는 시간이라 의미있었다!. 에러가 발생하였을때 이를 해결하여 코드를 돌아가게 하는 것도 중요하지만, 왜 이러한 에러사항이 생기는지에 대해 알고 넘어가야 된다고 생각한다.

<항해 4 일차>

4일차, 온보딩을 진행하는 과정속에서 다른 오류사항들을 마주하게 된다.

크게,

  1. orm이 작동하지 않는 문제

  2. 백단에서 던져주는 데이터를 프론트에서 인식을 못하는 문제



1. ORM 오작동 해결

  • Django는 기본적인 인증 시스템과 여러 가지 필드를 포함하고 있는 User모델을 기본적으로 제공해준다.
    • 하지만,
      이를 인식하지 못한채 , User라는 똑같은 이름의 모델을 사용하였다
    • 그랬기에, orm 오류부터 컬럼이 맞지않아 데이터가 기입되지 않은 오류를 맞이했다.

해결,

#.user/apps.py

   
class UserConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'user'


class Usersignups(AppConfig):
    
    name = 'usersignup'
  • 기존과 다르게 밑의 새로운 클래스를 추가
    • 이유는, 내가 만든 user table을 인식할수 있도록 이름을 변경했기때문에
      이를 인식할 수 있도록

#.user/models.py

from django.db import models

# Create your models here.


class UserSignup(models.Model):
  id = models.IntegerField(primary_key=True)
  user_name = models.CharField(max_length=50)
  password = models.CharField(max_length=100)
  created_at = models.DateTimeField(auto_now_add=True)
  • 변경한 user모델

#.user/views.py

from .models import UserSignup
  • 새로 변경한 모델을 import 시켜준다
profile
밑거름이라고생각합니다

0개의 댓글