# pyenv 
0. 환경
- centos 7.4

1. 설치 및 설정하기
- yum 을 이용한 설치
- ```
  # 사전 설치목록
  $ yum install -y  gcc gcc-c++ make git patch openssl-devel zlib-devel readline-devel sqlite-devel bzip2-devel
  $ git clone git://github.com/yyuu/pyenv.git ~/.pyenv
      ```
    - 환경변수에 선언해두기 (.bashrc 파일에 추가)
    - ```
  # pyenv path
  export PATH="$HOME/.pyenv/bin:$PATH"

  eval "$(pyenv init -)"
  eval "$(pyenv virtualenv-init -)"
  ```

2. pyenv 확인하기
- 사용가능한 pyenv 목록 확인하기
- ```
      [centos@centos ~]$ pyenv versions
      * system (set by /home/centos/.pyenv/version)
        3.6.5
  ```
- pyenv 변경하기
- ```
      [centos@centos ~]$ pyenv global 3.6.5
      [centos@centos ~]$ pyenv versions
        system
      * 3.6.5 (set by /home/centos/.pyenv/version)
      
      # 해당 shell 에서만 동작시키고 싶다면
      $ pyenv shell 3.6.5
  ```
    - pyenv 실행하기 및 종료하기
- ```
  [centos@centos ~]$ pyenv activate 3.6.5
  [centos@centos ~]$ pyenv deactivate
  ```

Posted by 감각적신사
,

Django + Apache 연동하기

  • 참고 URL

  • 웹서버와의 연동 필요성:

    • Django 의 runserver 기능은 개발의 편의를 위해 테스트 목적으로 제공되는 기능이다
    • Django 측에서도 실제 서비스 환경에서는 runserver 기능을 이용하는 것을 권장하지 않는다
      • 안정성과 성능 측면을 고려하지 않은 기능이기 때문이다
      • multi threading 처리도 불가하다
      • audit 기능과 같은 보안에 관련된 기본 설정도 불가하다
  • 테스트 환경

    • centos 7.5
    • python2.7.10
    • Django 1.11.15
    • apache 2.4
  • apache 설치

    • apache 2.4 다운로드 페이지 접속
    • 다운로드 목록
      • Httpd 2.4.35
      • Apache APR(Apache Portable Runtime) 1.6.5
      • Apache APR Util 1.6.1 (https://apr.apache.org/download.cgi)
      • PCRE(Perl Compatible Regular Expressions) 8.39 (ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/)
    • 다운로드 압축 해제
      $ tar xvfz httpd-2.4.35.tar.gz
      $ tar xvfz apr-1.6.5.tar.gz
      $ tar xvfz apr-util-1.6.1.tar.gz
      $ tar xvfz pcre-8.38.tar.gz
      
    • 컴파일 전 디렉토리 구조 정리
      {{ apache_home }}/httpd-2.4.35
          ㄴ srclib
                ㄴ apr       # apr-1.6.5 압축 해제한 것을 옮긴다
                ㄴ apr-util  # apr-util-1.6.1 압축 해제한 것을 옮긴다
      
    • 컴파일
      $ make && make install
      
    • 컴파일 후 apache 디렉토리 구조
      {{ apache_home }}/httpd-2.4.35  # 컴파일 실행했던 디렉토리
      {{ apache_home }}/apache2       # 컴파일에 의해 생성된 디렉토리
                          ㄴ bin
                          ㄴ conf
                          ㄴ ...
      
    • 설정 변경
      $ vi {{ apache_home }}/conf/httpd.conf
      # ServerName 127.0.0.1
      # Listen 8080   << 80 은 root 에게 부여되는 port 라 8080 으로 변경함
      
    • 실행
      $ {{ apache_home }}/apache2/bin/apachectl start (graceful)  # graceful 은 stop & start
      
  • django 프로젝트 생성

  • 연동하기

    • mod_wsgi 패키지 설치
      • 웹서버에서 받은 요청을 django 같은 python application 으로 전달해주는 interface 역할을 하는 패키지
        $ sudo yum search mod_wsgi
        $ yum install mod_wsgi      # search 목록에서 python 버전에 맞는 것을 설치한다
        
    • 아파치 설정 추가하기

      $ vi {{ apache_home }}/conf/httpd.conf
      
      # 접근 권한 추가
      <Directory />
          Require all granted
      </Directory>
      
      # django 프로젝트 연결
      <VirtualHost *:8080>
          Alias /static/ {{ django_project_path }}/static/
          <Directory {{ django_project_path }}/static>
              Order allow,deny
              Allow from all
          </Directory>
      
          WSGIScriptAlias / {{ django_project_path }}/{{django_project_app}}/wsgi.py
          <Directory {{ django_project_path }}/{{django_project_app}}>
            <Files wsgi.py>
                    Order allow,deny
                    Allow from all
            </Files>
          </Directory>
      </VirtualHost>
      
      # wsgi 패키지 로드
      LoadModule wsgi_module      /usr/lib64/httpd/modules/mod_wsgi.so
      
    • django 프로젝트에 wsgi.py 파일 추가

      $ vi {{ django_project_path }}/{{django_project_app}}/wsgi.py
      
      import os, sys
      
      path = os.path.abspath(__file__+'/../..')
      
      if path not in sys.path:
          sys.path.append(path)
      
      from django.core.wsgi import get_wsgi_application
      
      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project_app.settings")
      application = get_wsgi_application()


Posted by 감각적신사
,

모니터 없는 서버에서 robotframework 를 활용한 web browser 테스트 하기

  1. 테스트 환경

    • centos 7.4
    • Python 3.6.5
      • robotframework=3.0.4
      • robotframework-selenium2library=3.0.0
      • selenium=3.14.1
    • chromedriver 2.38
  2. headlness chrome

    • headlness chrome 이란?
       decktop 환경이 아니라 모니터가 존재 하지 않는 서버의 환경에서는 일반적인 방식으로는 크롬을 사용할 수 없다. 
       이를 해결해 주는 방식이 바로 Headless 모드이다. 
       브라우저 창을 실제로 운영체제의 '창' 으로 띄우지 않고 대신 
       화면을 그려주는 작업(렌더링)을 가상으로 진행해주는 방법으로 실제 브라우저와 동일하게 동작하지만 창은 뜨지 않는 방식을 말한다
      
    • headlness chrome 사용 예제

        *** Settings ***
        Library   Selenium2Library
      
        *** Test Cases ***
        Basic Test
            Open Html
      
        *** Keywords ***
        Open Html
            Open Browser      http://mrsence.tistory.com      headlesschrome
      
    • 활용
      • CI 서버(Jenkins) 에서의 동작이 가능하다
        • 빌드 후, 빌드된 web service 에 대한 테스트를 자동으로 할 수 있다
        • web service 가 정상 동작 중인지, 주기적으로 batch 형태로 서비스를 테스트 할 수 있다


Posted by 감각적신사
,

Robot framework 을 사용한 web page 테스트

  1. Prerequired

    • 관련 파이썬 라이브러리 설치
      # pip install --upgrade robotframework
      # pip install --upgrade robotframework-selenium2library
      
    • selenium 을 통해 webdriver 를 호출하기 위한 브라우저 모듈 설치
  2. Robot test 실행

     $ python -m robot.run {{실행파일}}
    
    • 실행 결과 를 xml 파일로 남긴다
      • output.xml
      • log.html
      • report.html
    • 예시
        MrSense:input mr.sense$ python -m robot.run input.robot
        ==============================================================================
        Input
        ==============================================================================
        Basic Test                                                            | PASS |
        ------------------------------------------------------------------------------
        Input                                                                 | PASS |
        1 critical test, 1 passed, 0 failed
        1 test total, 1 passed, 0 failed
        ==============================================================================
        Output:  /Users/mr.sense/Dev/robotframework/sample.code/robotframework/input/output.xml
        Log:     /Users/mr.sense/Dev/robotframework/sample.code/robotframework/input/log.html
        Report:  /Users/mr.sense/Dev/robotframework/sample.code/robotframework/input/report.html
      
  3. Input Tag 관련 테스트 파일

     *** Settings ***
     Library           Selenium2Library
    
     *** Test Cases ***
     Basic Test
         Open Html
         Insert Text To Input Field
         Insert File To Input Field
         Click The button
    
     *** Keywords ***
     Open Html
         Open Browser    http://localhost:8000/input.html   browser=chrome
         Maximize Browser Window
    
     Insert Text To Input Field
         Input Text    input-text    hello world
    
     Insert File To Input Field
         Choose File   input-file  /Users/mr.sense/Dev/input.html
    
     Click The button
         Click Element     input-button
    
  4. Click Event 관련 테스트 파일

     *** Settings ***
     Library           Selenium2Library
    
     *** Test Cases ***
     Basic Test
         Open Html
         Click The button
         Click The Selectbox
         Click The link
    
     *** Keywords ***
     Open Html
         Open Browser    http://localhost:8000/click.html   browser=chrome
         Maximize Browser Window
    
     Click The button
         Click Element     btn-click
    
     Click The Selectbox
         Select From List by Value    xpath=//select[@id="select-click"]    third
         Element Should Contain    select-click    third
    
     Click The link
         Click Link      /a.html
         Wait Until Page Contains    HIHIHI    2s
    
  5. Table 관련 테스트 파일 (id 없는 element 다루기)

     *** Settings ***
     Library           Selenium2Library
    
     *** Test Cases ***
     Basic Test
         Open Html
         Get Table Row Count
         Get Table Td text
    
     *** Keywords ***
     Open Html
         Open Browser    http://localhost:8000/table.html   browser=chrome
         Maximize Browser Window
    
     Get Table Row Count
         Assign Id To Element    xpath=//table[@class="xtable"]    my_table
         ${rowCount}=    Get Matching Xpath Count       .//table[@id="my_table"]/tbody/tr
         shouldBeEqualAsIntegers     3    ${rowCount}
    
     Get Table Td text
         Assign Id To Element    xpath=//table[@class="xtable"]    my_table
         ${cellValue}=  Get Table Cell    my_table   2   2
         shouldBeEqual  19  ${cellValue}


Posted by 감각적신사
,

Robot framework + Seleium

  1. Robot framework

    • 테스트 자동화 프레임 워크
    • 프로젝트는 GitHub 에서 호스팅 하고 있음
    • 설치:
        $ pip install robotframework
      
    • 표 형식의 테스트 데이터 구문이 있으며 키워드 기반 테스팅 방식을 사용함

      • 문법 가이드
      • 샘플

        # cat test.robot
        *** Settings ***
        Library           Selenium2Library
        
        *** Test Cases ***
        Google Devops And Find Eficode
            Open Browser To Google
            Search My blog
            Result Should Contain mrsence
        
        *** Keywords ***
        Open Browser To Google
            Open Browser    https://www.google.com    browser=chrome
            Maximize Browser Window
            Google Should Be Open
        
        Search My blog
            Input Text    lst-ib    mrsence tistory
            Press Key    lst-ib    \\13
        
        Result Should Contain mrsence
            Wait Until Page Contains    mrsence.tistory.com    10 s
        
        Google Should Be Open
            Location Should Contain    www.google.com
        
  2. seleium
    • 브라우저를 자동화 하는 tool
    • 다양한 브라우저 자동화 도구, API 및 프레임 워크의 핵심 기능을 가짐
    • SeleniumLibrary
      • Selenium 을 내부적으로 사용하는 Robot Framework 용 웹 테스트 라이브러리


Posted by 감각적신사
,
  1. opencv 란,

    • 실시간 이미지 프로세싱에 중점을 둔 라이브러리
    • 주요 지원 항목: TensorFlow , Torch / PyTorch 및 Caffe 의 딥러닝 프레임워크
  2. opencv-python

    • 설치:
    pip install opencv-python
    
  3. opencv 를 활용한 이미지 처리

    • 이미지 속 원 의 갯수 구하기
    import cv2
    import numpy as np
    
    path = '/Users/mr.sense/images/sample/colony.jpg'
    
    # 이미지 로딩
    img = cv2.imread(path)
    mask = cv2.threshold(img[:, :, 0], 255, 255, cv2.THRESH_BINARY_INV +  cv2.THRESH_OTSU)[1]
    
    stats = cv2.connectedComponentsWithStats(mask, 8)[2]
    label_area = stats[1:, cv2.CC_STAT_AREA]
    
    min_area, max_area = 50, 350  # min/max for a single circle
    singular_mask = (min_area < label_area) & (label_area <= max_area)
    circle_area = np.mean(label_area[singular_mask])
    
    n_circles = int(np.sum(np.round(label_area / circle_area)))
    
    print('Total circles:', n_circles)
    


Posted by 감각적신사
,

Python multiprocess vs multithread

  1. python GIL (Global Interprinter Lock)

    • 참고
    • 하나의 파이썬 인터프리터에서는 하나의 작업만 실행한다
    • GIL 회피 방법
      • multiprocess 를 사용한다 == 하나의 interpreter 를 실행하여 여럿의 프로세서를 구동한다
      • 구현 단에서, I/O bound 한 부분과 CPU bound한 부분을 나누는 것
      • GIL이 없는 Jython 이나 IronPython을 이용
  2. python multiprocess example

    • multiprocessing 패키지 소개
    • 샘플 테스트 코드

      from multiprocessing import Pool
      from datetime import datetime
      import random
      import time
      
      read_file = open("/Users/mr.sense/Dev/python/test/readfile.txt", 'r') // read 10000 lines
      write_file = open("/Users/mr.sense/Dev/python/test/writefile_multiprocess.txt", 'a')
      
      lines = read_file.readlines()
      read_list = []
      return_list = []
      
      for line in lines:
        line = line.replace('\n','')
        read_list.append(line)
      read_file.close()
      
      # sleep method
      def append_file(msg):
        sleep_time = random.randrange(1,10)
        time.sleep(sleep_time)
        write_file.write(msg+', sleep: '+str(sleep_time)+'\n')
        return msg
      
      # initialize pool
      pool = Pool(processes=1000) # start 1000 worker processes
      
      start = datetime.now()
      print 'start: '+str(start)
      
      # get result process
      for i in pool.imap_unordered(append_file, read_list):
        return_list.append(i)
      
      end = datetime.now()
      print 'end: ' + str(end)
      
      # get time
      print end - start
      
  3. python multithread

    • concurrent 패키지 설치 및 활용
    • 샘플코드

      from datetime import datetime
      import concurrent.futures
      import random
      import time
      
      read_file = open("/Users/mr.sense/Dev/python/test/readfile.txt", 'r') // read 10000 lines
      write_file = open("/Users/mr.sense/Dev/python/test/writefile_multithread.txt", 'a')
      
      lines = read_file.readlines()
      read_list = []
      return_list = []
      
      for line in lines:
        line = line.replace('\n','')
        read_list.append(line)
      read_file.close()
      
      def append_file(msg):
        sleep_time = random.randrange(1,10)
        time.sleep(sleep_time)
        write_file.write(msg+', sleep: '+str(sleep_time)+'\n')
        return msg
      
      start = datetime.now()
      print 'start: '+str(start)
      
      with concurrent.futures.ThreadPoolExecutor(max_workers=1000) as exe:
        write_result = {exe.submit(append_file, line): line for line in read_list}
        for future in concurrent.futures.as_completed(write_result):
            line = write_result[future]
            try:
                data = future.result()
            except Exception as exp:
                print("%r generated an exception: %s" % (line, exp))
      
        end = datetime.now()
        print 'end: ' + str(end)
        print end - start


'개발 > python' 카테고리의 다른 글

Robot framework + Seleium -- (1)  (0) 2018.09.09
python - opencv 를 이용한 이미지 처리  (0) 2018.08.25
django mysql rest api project  (0) 2018.03.11
Django 프로젝트에서 batch job 돌리기  (0) 2018.01.23
Django 프로젝트  (0) 2017.11.29
Posted by 감각적신사
,
  1. settings.py 설정

    • mysql 데이터베이스에 사용할 app model 의 initial.py 를 생성한다
    • $ python manage.py makemigrations
      
    • mysql 데이터베이스에 app model table 을 생성한다
    • $ python manage.py migrate
      
      # Database 설정
      DATABASES = {
        # 기본으로 default 의 database 명을 받아 DB migration 을 하게 된다
        'default': {
            'ENGINE': 'django.db.backends.mysql',  # mysql db 를 사용한다
            'NAME': 'database1',                   # database 명
            'USER': 'testuser',                    # 사용자 id
            'PASSWORD': 'testpasswd',              # 사용자 password
            'HOST': 'localhost',                   # ip address
            'PORT': '3306',                        # port
        },
        # 멀티 데이터베이스를 사용하게 될 경우, setting
        'database2': {                             # database 명을 따라간다
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'database2',
            'USER': 'testuser',
            'PASSWORD': 'testpasswd',
            'HOST': 'localhost',
            'PORT': '3306',
        }
      }
      
      # 라우터를 통해 앱 별로 사용할 데이터 베이스를 선택하도록 한다
      DATABASE_ROUTERS = [
        # 프로젝트명.python패키지.python파일명.python클래스
        'django_multi_databases.MultiDatabasesRouter.Router',
      ]
      
  2. Router.py (선택사항)

    • 멀티 데이터베이스 사용시, default 를 사용하지 않을 app 에 대해서만
    • $ python manage.py migrate {app_name} --database={database_name}
      
      class Router(object):
        app_dictionary = {
            'app1' : 'default',
            'app2' : 'database2',
        }
      
        def db_for_read(self, model, **hints):
            return self.app_dictionary[model._meta.app_label];
      
        def db_for_write(self, model, **hints):
            return self.app_dictionary[model._meta.app_label];
      
        def allow_migrate(self, db, app_label, model_name=None, **hints):
            return True
      
  3. models.py

    • mysql 맵핑 object 생성

      # -*- coding: utf-8 -*-
      from __future__ import unicode_literals
      
      from django.db import models
      from django.utils import timezone
      
      class DB1Model(models.Model):
        # 기본적으로 primary 를 선언하지 않으면 id 라는 auto increments 컬럼이 생성된다
        title = models.CharField(max_length=255)
        content = models.TextField()
        likes = models.BigAutoField()
        lastModified = models.DateTimeField(default=timezone.now)
      
  4. Serializer.py

    • DB model 과 django 프레임워크 의 object 를 연결

      class DB1ModelSerializer(serializers.ModelSerializer):
      
        class Meta:
            model = DB1Model
            fields = ('id', 'title', 'content', 'likes, 'lastModified')
      
  5. views.py

    • django 프레임워크 에서 CRUD 하는 로직 생성

      class DB1ModelListCreateAPIView(generics.ListCreateAPIView):
        http_method_names = ['get', 'post']
      
        queryset = DB1Model.objects.all()
        serializer_class = serializers.DB1ModelSerializer
      
      class DB1ModelRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
        http_method_names = ['get', 'put', 'delete']
        serializer_class = serializers.DB1ModelSerializer
      
        def get_object(self):
            queryset = self.filter_queryset(self.get_queryset())
            filter_kwargs = {'id': self.kwargs['id']}
            model_instance = generics.get_object_or_404(queryset, **filter_kwargs)
            return model_instance
      
  6. urls.py

    • CRUD 동작 과 RESTful API 와 연결

      url(r'^/v1/dbmodel/$', views.DB1ModelListCreateAPIView.as_view(), name="api-dbmodel-lc"),
      url(r'^/v1/dbmodel/(?P<id>[^/]+)/$', views.DB1ModelRetrieveUpdateDestroyAPIView.as_view(), name="api-dbmodel-rud"),


Posted by 감각적신사
,

Django 프로젝트에서 batch job 돌리기

  1. django-background-tasks 모듈 활용하기

    • docs
    • 샘플 프로젝트
    • 모듈 install:
      • $ pip install django-background-tasks
        # django-compat 에 대한 의존성이 있기 때문에 관련하여 추가 업데이트가 필요할 경우도 있다
        
    • 모듈 관련 설정
      • # settings.py
          INSTALLED_APPS = (
              # ...
              'background_task', # batch job 관련 library
              # ...
          )
        
      • $ python manage.py makemigrations background_task
        $ python manage.py migrate
        
  2. 동작방식

    • django 웹과 별도의 프로세스로 동작 시키기
      • 별도의 명령어 실행
      • $ python manage.py process_tasks
        
    • django 웹안에서 동작 시키기

      • API 형태로 호출하여 실행
      • # urls.py
            urlpatterns = [
                   url(r'^v1/tasks/$', views.tasks, name='tasks'),
              ]
        
        # views.py
         @csrf_exempt
         def tasks(request):
             if request.method == 'POST':
                 message = request.POST.get('message', False)
                 return demo_task(request)
             else:
                return JsonResponse({}, status=405)
        
         @background(schedule=60)
         def demo_task(message):
            logger.debug('demo_task. message={0}'.format(message))


'개발 > python' 카테고리의 다른 글

Python multiprocess vs multithread  (0) 2018.05.24
django mysql rest api project  (0) 2018.03.11
Django 프로젝트  (0) 2017.11.29
Django 프로젝트 생성 및 App 만들기  (0) 2017.08.27
Python Django WEB project 개발하기1  (0) 2016.08.17
Posted by 감각적신사
,

Django 프로젝트

개발/python 2017. 11. 29. 00:56

Django 앱 만들기

참고

  1. 시작하기 전에

    • 프로젝트 vs. 앱
      • 프로젝트는 다양한 앱을 포함
      • 앱은 웹 어플리케이션의 기능 (e.g., 웹 블로그시스템,공공 기록의 데이터베이스 또는 간단한 투표 앱)
    • virtualenv: 개발환경에서 독립된 개발환경을 제공해주는 프로그램

          # 패키지 설치
          $ sudo pip install virtualenv
      
          # 프로젝트 생성
          $ virtualenv venv_projat
          New python executable in /naver/venv/venv_projat/bin/python
          Installing setuptools, pip, wheel...done.
      
          # 가상환경 실행
          $ source ./venv_projat/bin/activate
      
          # 가상환경 에서 사용하는 python moduel 확인
          $ pip list
          Django (1.11.3)
          pip (9.0.1)
          pytz (2017.2)
          setuptools (36.2.5)
          wheel (0.29.0)
      
          # 가상환경 종료
          $ deactivate
      
  2. Django 의 구조

    • MVT 모델
      • 좋은 참고자료
      • 모델 Model:
        • DB 구조를 설정하는 컴포넌트, ORM 방식을 사용하여 SQL 문을 직접 사용하지 않고 파이썬 객체로 접근
        • 하나의 class 가 하나의 table 을 의미한다
      • 뷰 View: (== MVC 모델의 Controller)
        • 데이터를 입력받거나 표시하는 컴포넌트
      • 템플릿 Templates: (== MVC 모델의 View)
        • 사용자의 입력과 이벤트에 반응하여 Model 과 View 를 업데이트
        • 디자인 영역의 분리 및 재사용서을 높이기 위해 HTML 구조만 따로 모아놓은 것
        • {{변수}}, {{% 태그 %}}
    • 흐름도

  3. Django 프로젝트

    • 생성

        # django-admin.py {{실행 파라미터}} {{프로젝트명}}
        $ django-admin.py startproject djangoproject
      
    • 프로젝트 구조

        djangoproject/
            ㄴ manage.py # 초기화, 마이그레이션, 실행 등을 수행하는 파일
            ㄴ djangoproject/
                    ㄴ __init__.py
                    ㄴ settings.py # 웹사이트 설정이 있는 파일
                                - ALLOWED_HOSTS: 접근 가능 호스트 정리
                                - DATABASES: 사용할 DB 정보
                                    - ENGINE:
                                        'django.db.backends.sqlite3'
                                        'django.db.backends.postgresql_psycopg2'
                                        'django.db.backends.mysql'
                                        'django.db.backends.oracle'
                                - INSTALLED_APPS:
                                    - django.contrib.auth – 인증시스템
                                    - django.contrib.contenttypes – 컨텐츠타입 프레임워크.
                                    - django.contrib.sessions – 세션프레임워크
                                    - django.contrib.sites – 한번의 Django설치로 여러 사이트 관리를 위한 프레임워크.
                                    - django.contrib.messages – 메시징 프레임워크
                                    - django.contrib.staticfiles – 정적파일을 관리하기 위한 프레임워크.
                                    - **신규 생성할 앱을  프로젝트에 추가한다.**                                
                    ㄴ urls.py # urlresolver 가 사용하는 패턴 목록을 포함
                    ㄴ wsgi.py # wsgi 호환 서버에서 서비스를 하기 위한 진입점
      
  4. Django 앱

    • 생성
      $ python manage.py startapp django1stapp
      
  5. 실행

         $ python manage.py makemigrations
         # model 의 변화 사항을 migration 폴더에 python 파일로 저장함.
         # 위에서는 ./migrations/  폴더내에 0001_initial.py 파일이 새로 생김
         # 아직 database 에 model table 생성된것은 아님
    
         $ python manage.py migrate
         # db table 생성
    
         $ python manage.py runserver ip:port
         # django project run


Posted by 감각적신사
,