선발대

[스파르타] Django 심화반 1주차 (완강) 본문

스파르타코딩클럽/강의 정리

[스파르타] Django 심화반 1주차 (완강)

신선한 스타트 2022. 3. 8. 01:01

수업목표

 

  1. 다수의 개발자가 함께 작업하기에 편한 프로젝트를 만든다.
  2. 자동화 테스트의 중요성을 이해한다.
  3. poetry, black, isort, mypy 등 개발자를 도와주는 툴을 익힌다.

 

  01. 모던한 엔터프라이즈 django 개발을 소개합니다.  

 

강의 시작 전에 알아야 할 것

 

  • Python 설치: 스스로 python을 설치하고, PATH 변경 가능한지. venv, 가상환경 사용 능력.
  • Python:
  • 변수, 상수, 리터럴에 대한 이해
  • 지역변수, 전역변수, 변수의 스코프 설명
  • Mutable, Immutable 차이 설명
  • 객체지향: 객체지향의 4대 원칙(캡슐화, 상속, 추상화, 다형성)

 

  • Django:
  • Django Http Request를 input 받고, Http Response를 output 한다는 점
  • Django ORM을 사용해서 Model 클래스를 정의하는 법
  • Django ORM을 사용해서 기본적인 CRUD를 수행하는 법

 

  • SQL:
  • 간단한 CRUD
  • join, inner join, left join, outer join 등, 각 join의 차이점 숙지

 

강의를 통해 얻을 수 있는 것

 

  • black, isort
  • 타입힌트 Mypy
  • 자동화테스트
  • Github Action 사용하는 간단한 Continuous Integration
  • F expression, Prefetch object
  • API 문서화, Swagger, Pydantic의 간단한 사용법

 

  02. Poetry 설치  

 

Poetry

 

  • 매번 pip freeze 할 필요없고, 알아서 poetry.lock으로 종속성 관리해줌
  • PEP 518 표준인 pyproject.toml로 프로젝트 관리 가능.
  • pip보다 좀 더 똑똑한 dependency resolving

 

Poetry 설치

 

 

  03. Django, django-ninja 설치  

 

django, django-ninja 설치

 

  • pycharm에서 poetry executable로 새 프로젝트 생성
  • django 설치: poetry add django==4.0 django-ninja==0.16.1
  • django-admin startproject <프로젝트명>
  • python manage.py migrate
  • python manage.py runserver
  • http://127.0.0.1:8000/

 

Django-ninja 첫 API 만들어보기

 

from django.contrib import admin
from django.urls import path
from ninja import NinjaAPI

# django-ninja의 NinjaAPI 객체를 import 함
api = NinjaAPI()


# view function을 데코레이터 사용해서 감싸는 방식
# flask랑 비슷해서 익숙함
# api 객체의 urls를 'api/' 경로에 등록함
@api.get("/add")
def add(request, a: int, b: int):
    return {"result": a + b}


urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/", api.urls),
]

 

Swagger 사용

 

  • route 함수의 인자, return 값을 감지하여 fastAPI가 자동으로 문서 생성해준다.

 

git init, .gitignore

 

  • git init
  • .gitignore
# Idea Project
.idea/

# Python
__pycache__
# 가상환경은 프로젝트 밖에 있으므로, git ignore 하지 않음
  • git add .
  • git commit -m "initial commit"
  • db.sqlite3도 커밋 (나중에 MySQL로 변경)

 

정리

 

  • pip가 아니라 poetry로 dependency 관리. requirements.txt는 이제 버려~
  • django, django-ninja 설치
  • django-ninja는 swagger UI를 자동으로 만들어준다.
  • git init, git commit, .gitignore(버전관리 막기)

 

  04. Black 설치  

 

Black 소개 & 설치

 

  • black: code formatter, 개발자들끼리 일관된 코드스타일을 유지하도록 도와줌.
  • black 설치: poetry add black==21.12b0

 

Black 실행해보기 & 설정

 

  • 프로젝트 root 디렉터리에서 poetry run black .
  • pyproject.toml
# pyproject.toml
[tool.black] # 대괄호: 섹션
line-length = 120 # black에 관련된 설정

 

정리

 

  • git commit 잊지 말기
  • 코드 포매터: 여러 개발자가 하나의 리포지토리에서 협업할 때, 일관된 코드 스타일 유지하도록 함.
  • 코드 포매터 black 설치함
  • black에 약간의 커스텀을 더함
  • pyproject.toml에서 여러가지 커스텀 설정을 할 수 있도록 통일함


  05. Django-stub, Mypy 설치  

 

Mypy 소개

 

## django-stub, mypy

Package operations: 6 installs, 0 updates, 0 removals

 • Installing toml (0.10.2)
  • Installing django-stubs-ext (0.3.1)
  • Installing mypy (0.910)
  • Installing types-pytz (2021.3.2)
  • Installing types-pyyaml (6.0.1)
  • Installing django-stubs (1.9.0)

 

Mypy 설정

 

[tool.mypy]
plugins = ["mypy_django_plugin.main"]
python_version = 3.9
strict = true 
# argument, return 값에 type hint가 제대로 되어있는지 검사

[[tool.mypy.overrides]]
module = "*.migrations.*"
ignore_errors = true

[[tool.mypy.overrides]]
module = "manage"
ignore_errors = true

[tool.django-stubs]
django_settings_module = "sparta.settings"

 

모듈별 설정

 

 

Mypy 실행

 

  • poetry run mypy .
poetry run mypy .
sparta/settings.py:28: error: Need type annotation for "ALLOWED_HOSTS" (hint: "ALLOWED_HOSTS: List[<type>] = ...")
Found 1 error in 1 file (checked 6 source files)
  • type 없는 곳을 수정해준다. > settings.py
  • ALLOWED_HOSTS: List[str] = []
  • urls.py
  • 다시 mypy 실행하면 Success 뜬다.

 

정리

 

  • 정적 분석기: runtime에 발생할 문제를 코드 실행 없이도 미리 알려준다.
  • Mypy는 정적분석기임. django에서 mypy 잘 사용하려면 django-stub 설치가 필요함.
  • Mypy 실행도 성공했음.

 

  06. 테스트 실행해보기  

 

첫 번째 테스트 파일 만들고 실행하기

 

  • 파이썬 패키지, 파일 생성하기. sparta > tests(패키지) > __init.py__, test_view.py 
# test_view
from django.test import TestCase

class TestView(TestCase):
	def test_add_view(self) -> None:
    	result = self.client.get("/api/add", {"a":1, "b":3})
        self.assertEqual(result.status_code, 200)
        self.assertEqual(result.json(), {"result": 4})
  • 실행할 때: python manage.py test (poetry run python manage.py test 도 가능)

 

파이참으로 실행하면 에러 발생함

 

  • 터미널로 test 실행하면 디버깅 안됨. 파이참으로 실행해도 에러가 남.
  • django-aware 하지 않은 일반 unittest로 test 실행해서 발생하는 것임.
  • 따라서 설정 변경 필요.
  • 1. Enable Django Support 체크
  • 2. Edit Configuration > 이미 생성된 테스트 configuration 삭제
  • 실행 결과 보면 파이참의 실행명령 변경 확인 가능. 기본 unittest는 안 쓰게 됨. 중단점도 체크.

 

정리

 

  • 첫 test case 만들었다.
  • 파이참에서 바로 테스트 실행하고 디버깅도 할 수 있게 됨.
  • print()로 디버깅 하지 말기.

 

  07. 자동화 테스트가 필요한 이유  

 

  • 테스트는 개발자가 수정을 두려워하지 않도록 만들어 준다.
  • 코드로 코드를 검증하기 때문에 반복적인 실행에도 유리함.


  08. isort 설치하기  

 

isort 설치하기

 

  • isort: import 순서를 정렬해준다.
  • poetry add isort==5.10.1
  • black과의 compatibility를 위해 pyproject.toml에 설정 추가하기
[tool.isort]
profile = "black"
  • isort 실행: poetry run isort .


  09. black, isort, mypy 테스트까지 한 번에 실행하기  

 

test.sh 파일 만들기

 

  • 커밋할 때마다 black, isort, mypy 등을 일일이 명령어로 실행하면 너무 번거로움.
  • 하나의 스크립트로 만들어서 한번에 실행하자.
## test.sh (window용)
#!/usr/bin/env bash

echo "Run black"
poetry run black .

echo "Run isort"
poetry run isort .

echo Run "Run mypy"
poetry run mypy .

echo Run "Run tests"
python manage.py test

echo "Done. Please check above."
sleep 9999
  • 실행하는 법: ./test.sh
  • set -euo pipefail: 스크립트 명령을 실행하다가 중간에 실패하는 경우 더 이상 진행하지 않음.
  • 만약 mypy 검사에서 에러가 있다면 수정한 후 다시 스크립트 실행함. 


  10. Github Action으로 push 할 때마다 테스트 하기  

 

Continuous Intergration

 

  • Cl이 필요한 이유:
  • 테스트가 끝난 코드(master)에서 새로운 branch 생성함 > 새로운 branch에서 작업함 >
  • 로컬에서 테스트함. > PR 올림. 코드리뷰, 테스트 > 개발서버에 배포 >
  • develop 서버에서 테스트 > master에 merge, 테스트, 배포함.
  • 테스트를 자동화해서 에러를 줄이고, 반복 작업 시간을 줄여서 더 효율적으로 일함.

 

Git Action

 

  • github에 push 할 때마다 테스트가 자동으로 실행되도록 하기.
# .github/workflow/ci.yaml
name: Django CI

# 액션이 언제 실행되는지 정의함. on: push는 push할 때마다 실행됨.
on:
  push:

# 하나의 workflow는 여러 개의 job으로 구성됨.
# 아래는 ci라는 이름(id)의 job 하나만 정의해서 사용함.
jobs:
  ci:
  	# runs-on: job이 실행되는 machine을 의미함.
    # github가 제공하는 ubuntu-latest(현재버전 20)을 사용함.
    runs-on: ubuntu-latest
    # steps: 하나의 job은 여러 개의 step으로 구성됨. 
    # step은 명령을 실행하거나 다른 action을 실행함.
    steps:
      - name: Check out the codes
      	# uses: 실행할 action을 가리킴.
        uses: actions/checkout@v2

      - name: Setup python environment
        id: setup-python
        uses: actions/setup-python@v2
        
        # with: action에 전달한 parameter 변수임
        with:
          python-version: 3.9.9

      - name: Install Poetry
      	# run: 실행할 명령어임
        # run: | : yaml 문법임. |(파이프라인)을 사용해 value가 여러 줄(multiline)이라는 것을 의미함.
        run: |
          curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
          echo "${HOME}/.poetry/bin" >> $GITHUB_PATH

      - name: Install dependencies
        run: |
          ${HOME}/.poetry/bin/poetry install

      - name: Test python project
        run: |
          poetry run python manage.py test
  • push 될 때마다 우분투에서 파이썬 설치하고, poetry나 django 등 종속성 설치하고, test 실행함.

 

  11. Pycharm에서 django 실행하기  

 

  • django server도 테스트와 마찬가지로 파이참에서 실행할 수 있도록 변경함.
  • Run/Debug Configurations에서 + 버튼 눌러서 Django Server 추가함. (이름은 Run으로 지음)


  12. Mysql 설치하기  

 

Docker Desktop 설치

 

  • 이미 mysql 설치했다면 건너뛰어도 괜찮음.
  • 내 컴퓨터에는 에러가 나서 4.4.4 버전으로 설치했더니 해결되었음.

 

Pycharm으로 데이터베이스 연결하기

 

  • 콘솔에서 입력. CREATE DATABASE sparta;
  • 우측 데이터베이스 탭에서 + 누르고 MySQL 선택.
  • SELECT VERSION(); : 설치한 mysql 버전 확인.
  • SELECT NOW(); : 한국시간으로 제대로 나오는지 확인.

 

Django와 Mysql 연결하기

 

  • pymysql 설치: poetry add pymysql==1.0.2 types-PyMySQL==1.0.6
  • settings.py 수정하기
import pymysql
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
pymysql.install_as_MySQLdb()

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "sparta",
        "USER": "root",
        "PASSWORD": "22380476",
        "HOST": "localhost",
        "PORT": "3306",
    }
}
  • ./test.sh 실행

 

  13. 1주차 마무리  

 

  • 끝~


  1주차 숙제) 공식 문서 읽기  

 

  • mypy, black, django-ninja의 공식문서 원하는만큼 읽어오기
Comments