python으로 개발을 할 때 가상환경을 설정하는 상황이 꽤나 많아서 직접 포스팅을 하기로 하였습니다.


배경

파이썬으로 개발 혹은 어떠한 소프트웨어를 실행 할 때, 파이썬으로 된 환경에서 실행을 하려면 파이썬버전부터 해서 pip모듈까지 환경에 따라 설정해야 할 부분이 많은데 pyenv, virtualenv 그리고 autoenv를 이용하면 개발 하거나 파이썬 환경 세팅을 더 편하게 할 수 있다.


우선 요약

  • pyenv : python의 가상환경을 설정 할 수 있도록 해주는 도구로 여러 버전의 파이썬을 사용 할 수 있다.

  • virtualenv : python의 가상환경으로 정해진 버전에서 pip모듈들을 각 가상환경에서 설치하고 실행 할 수 있도록 해준다.

  • autoenv : 특정 디렉토리에 들어갔을 때 virtualenv를 자동으로 실행시켜줍니다.


pyenv

pyenv란 python 버전에 따라서 가상환경 설정을 할 수 있도록 도와주는 도구입니다.

설치는 맥에서 아래와 같습니다.

$ brew install pyenv


그 다음 pyenv init~/.bash_profile에 추가합니다. bash_profile에 추가하는것은 현재 OS(Mac이나 Linux)에 환경변수를 설정하는 부분이며 아래와 같습니다.

$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile


다음 아래와 같은 명령어로 현재 pyenv에서 사용 가능한 파이썬 버전들을 볼 수 있습니다.

$ pyenv versions
* system (set by /Users/taewoo/.pyenv/version)
  3.5.2
  3.5.2/envs/LinkU
  3.5.2/envs/pytest_practice
  3.5.2/envs/tdd_book_practice
  3.6.0
  3.6.0/envs/FoodGroup
  3.6.0/envs/LinkU
  3.6.0/envs/djangogirls
  FoodGroup
  LinkU
  LinkU_deprecated
  djangogirls
  pytest_practice
  tdd_book_practice


다음 아래와 같이 pyenv install –list를 통해서 pyenv에 설치 할 수 있는 파이썬 버전들을 볼 수 있으며 해당 버전을 설치하면 됩니다.

$ pyenv install --list

...

$ pyenv install [version]

예시

$ pyenv install 3.5.2


최신 python 버전들을 사용하기 위해서는 pyenv를 git pull하거나 update를 해줘야하는데 update의 명령어가 더 편합니다.

$ pyenv update


virtualenv

virtualenv를 통해서 가상환견을 설정하고 그 가상환경 설정마다 pip 모듈을 설치해 현재 컴퓨터의 환경과 독립적으로 파이썬만의 환경을 설정 할 수 있습니다.

다음 아래처럼 설치를 해줍니다.

$ brew install pyenv-virtualenv


pyenv와 똑같이 아래처럼 ~/.bash_profile에 추가합니다.

$ 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile
$ source ~/.bash_profile


이제 실제로 가상환경을 만들어 보겠습니다. 사용예제는 아래 형태와 같으며 실제 명령어는 그 아래와 같습니다.

$ pyenv virtualenv [python version] [virtualenv name]
$ pyenv virtualenv 3.5.2 virtualenv-test


실제로 가상환경이 만들어지면 아래와 같이 “pyenv activate [virtualenv name]”을 명시하시면 되며 나갈 때는 반대로 “pyenv deactivate”을 통해서 나갈 수 있습니다.

  • pyenv activate [virtualenv name] : [virtualenv name]라는 이름의 가상환경 실행(사전에 가상환경이 만들어져 있어야함)
  • pyenv deactivate : 현재 shell에서 실행된 가상환경을 종료

가상환경이 세팅되면 커맨드 라인 제일 앞줄에 (virtualenv name)와 같이 가상환경이 실행되어 있음을 자동으로 나타내줍니다.

$  pyenv activate virtualenv-test
$ (virtualenv-test)...
$ (virtualenv-test)...pyenv deactivate
//원상태로의 복귀


autoenv

autoenv는 특정 디렉토리에 들어갔을 때 virtualenv가 자동으로 실행 될 수 있도록 도와주는 도구입니다.

설치는 아래와 같습니다.

$ brew install autoenv


똑같이 이제 ~/.bash_profile에 추가를 합니다.

$ echo 'source /usr/local/opt/autoenv/activate.sh' >> ~/.bash_profile
$ source ~/.bash_profile


사용하는 방법은 가상환경을 실행하려는 디렉토리에서 다음과 같이 .env파일을 만들고 .env 파일 안에 아래 명령어처럼 원하는 가상환경을 입력해주시면 됩니다.

$ touch .env
$ echo "pyenv activate [virtualenv name]" > .env

예시는 아래와 같습니다.

$ touch .env
$ echo "pyenv activate virtualenv-test" > .env

이제 해당 디렉토리에 들어갈때마다 virtualenv가 실행이 됩니다.(해당 환경이 본 글과 같은 경우 virtualenv-test로 나옵니다.)

하지만 deactivate는 꼭 수동으로 해줘야합니다.

ReactJS에서 생긴 오류에 대해서 하나씩 기억하기 위해 포스팅하려고 한다.


문제

React를 Webpack을 통해서 컴파일 할 때 다음과 같은 오류가 뜬적이 있는데

ERROR in multi (webpack)-dev-server/client?http://0.0.0.0:7777 webpack/hot/dev-server ./src/index.js

Module not found: Error: Can't resolve 'babel' in '/Users/taewoo/Documents/ReactJS projects/react-tutorial'

BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.

“It’s no longer allowed to omit the ‘-loader’ suffix when using loaders.”를 봐서 더 이상 “-loader”를 생략하면 안된다라는 의미같다.


해결

구글링을 통해 보니 아래와 같이 webpack.config.js에서 ‘babel’을 ‘babel-loader’로 고쳐주면된다.

  • loader: 'babel' -> loader: 'babel-loader'

webpack.config.js

module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query: {
                    cacheDirectory: true,
                    presets: ['es2015', 'react']
                }
            }
        ]
    }


참고자료

onDragListener가 아닌 onTouchListener를 이용해서 드래그를 구현할 때 생겼던 문제점이 있어서 기억해두고자 포스팅한다.


배경

안드로이드 프로젝트를 작게 진행하고 있는데 onTouchListener에서 ACTION_UP에 관련된 코드를 작성하였지만 작동하지 않은 사례가 있어서 기억하고자 포스팅한다.


코드 상황

아래와 같은 코드로 처음에 제작을 하였으며 onTouch안에다가 함수가 실행되고 Action Value가 어떤것인지 알 수 있도록 로그 코드를 작성하였으며 각 Action Value에 따라서도 case문을 타고 들어갔음을 알기위해 로그 코드를 작성하였습니다.

imageView_Lv1alarmClockCancel.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                Log.e("onTouchTest", "onTouch Entered");

                int action = motionEvent.getAction();

                Log.e("onTouchTest", "Action Value : " + action);
                switch (action) {

                    case MotionEvent.ACTION_DOWN:
                        Log.e("onTouchTest", "ACTION_DOWN");
                        // ...Dragging View Codes
                        break;

                    case MotionEvent.ACTION_UP:
                        Log.e("onTouchTest", "ACTION_UP");
                        // ...
                        break;

                    default:
                        break;
                }
                return true;

            }

        });


결과는 아래와 같습니다. 화면을 터치하는 순간 ACTION_DOWN(Action Value = 0)이 되면서 case문을 타고 가지만 드래그를 시행하고 모든 작업을 마쳤을 때 화면에서 손을 떼었을 때 ACTION_UP이 아닌 ACTION_CANCEL(Action Value = 3)이 들어오는 것을 확인 할 수 있습니다.

즉, onTouch의 함수에서는 화면을 터치했는지 안했는지만을 확인하며 그에 대한 값들만 ACTION 값으로 받아옴을 확인 할 수 있습니다.

03-09 20:01:31.198 7117-7117/com.unopenlab.iamalarm E/onTouchTest: onTouch Entered
03-09 20:01:31.198 7117-7117/com.unopenlab.iamalarm E/onTouchTest: Action Value : 0
03-09 20:01:31.198 7117-7117/com.unopenlab.iamalarm E/onTouchTest: ACTION_DOWN
03-09 20:01:31.241 7117-7117/com.unopenlab.iamalarm E/onTouchTest: onTouch Entered
03-09 20:01:31.242 7117-7117/com.unopenlab.iamalarm E/onTouchTest: Action Value : 3


참고자료

django.test.Client를 통해서 요청 및 응답에 대한 테스트를 간단하게 짜보자


이전 포스팅

이전에 HttpResponse를 이용해서 간단하게 테스트하기를 통해서 HttpResponse객체를 생성하여 요청과 응답에 대한 테스트를 하는 내용에 대해서 작성하였는데 같은 기능을 이번에는 Django가 제공하는 client객체(Fixture)를 이용해보자


다른점

HttpResponse와 달리 django.test.Client를 이용하면 장고 에뮬레이팅에 의해서 실행되기 때문에 서버를 돌릴 필요가 없게 됩니다. Unit Test와 같은 단위 테스팅에 적합합니다.


사용법

기본적인 GET과 POST요청에 대한 사용법은 아래와 같다.

도메인을 함께 적어주는게 아니라 도메인 다음부터 오는 path을 적어줘야한다.

from django.test import Client

client = Client()

...
#GET
response = client.get('path', {'json': 'json', 'json data': 'json data'})

...
#POST
client.post('path', data={'json': 'json'})

...


GET

url을 명시해주고 그 다음에 Query String을 넘겨서 key-value 쌍으로 넣어주시면 됩니다.

from django.test import Client

client = Client()
#GET
response = client.get('url', {'json': 'json', 'json data': 'json data'})

response에는 응답이 오게 됩니다.


POST

url을 명시해주고 그 다음에 담을 데이터를 key-value 쌍으로 넣어주시면 됩니다.

from django.test import Client

client = Client()
#POST
response = client.post('url', data={'json': 'json'})

이 또한 마찬가지로 response에 응답이 오게 됩니다.


Response

응답에 대한 값이나 처리를 하게되는 경우도 있게 되는데 기본적으로 값을 가져오는 것은 다음과 같습니다. HttpResponse와는 다르게 테스팅 하기위한 몇가지 요소도 포함이 되어있습니다. 참조


  • content는 응답에서 body부분을 bytestring으로 가져오는 객체입니다.
response.content


  • context는 response content에서 렌더링한 template들을 반환합니다. 그 반환된 템플릿에서 특정한 값을 가져오고 싶다면 다음 아래처럼 가져올 수 있습니다.
reponse.context['name']


  • Content-Type이 application/json일 때 .json.loads() 혹은 .json()['name']으로 가져 올 수 있습니다.
response.json.loads()
# or
response.json()['name']


참고자료

Django에서 makemigrations와 migrate의 차이는 무엇일까?


Django 홈페이지

Django Migrations에 보면 간략하게 소개가 되어있다.


차이

장고 공식 홈페이지에 들어가면 아래처럼 간략하게 설명이 나와있다.

Django


  • makemigrations : models.py에서 적용한 변경사항이나 추가된 혹은 삭제된 사항들을 감지하여 파일로 생성
  • migrate : 적용되지 않은 migrations들을(설정값들을) 적용시키는 역할


즉, makimigrations는 장고에서 제공하는 모델의 변경사항들을 감지하고 기록하는 역할을 하며 migrate는 그러한 기록된 파일들과 설정값들을 읽어서 그 변경사항을 db에 저장하는 역할을 한다.