MTV 또는 MVT 패턴이라 부르며, 세부적으로는 M(Model) T(Template) V(View)를 의미한다. 여기서, View의 정의가 굉장히 헷갈리게 되었던 것 같다. 기본적으로 Java/Spring Boot에서의 MVC 패턴에서의 View와 동일한 역할일 것이라고 생각했으나, 오히려 Django에서의 View는 Controller와 매핑되며, 오히려 Template이 View를 의미한다는 것이 주의해야할 점이다.
Model: Django와 DB를 연결시켜주는 코드이며, DB Table과 매핑
Template: 사용자에게 제공될 결과물의 형태를 의미
View: 사용자의 요청을 받아 처리하는 웹 사이트의 로직을 가지는 코드
(출처: 현로그 블로그, 2023. 12. 14)
Project와 App의 구분은 Setting.py의 유무로 구분할 수 있다.
# 가상환경 생성
python3 -m venv {생성할 디렉토리명}
# 가상환경 접속
source ./bin/activate
# 가상환경 종료
deactivate
Q. 파이썬에서 가장환경이 왜 필요한가?
A. 프로젝트를 배포하면 원격 서버에 따로 패키지들을 설치해 줘야 하는데, 내가 이 프로젝트만을 위해서 설치한 패키지들이 어떤 건지 확인할 수 있다.
그리고 시간이 지남에 따라 패키지들이 업데이트되는데, 이것저것 업데이트를 하다 보면 서로 의존적인 패키지들 사이에 버전이 맞지 않아 호환이 되지 않는 경우들이 생긴다.
파이썬 버전 자체가 다른 환경인 경우도 있겠다. 프로젝트를 배포하려는 서버에는 파이썬 2만 설치된 경우도 있고, 2와 3이 같이 있는 경우도 있는 등 다양한 환경이다.
mkdir django_sample
cd django_sample
django-admin startproject {프로젝트명}
django-admin은 django 프로젝트를 관리하는 여러 기능을 가지고 있다.
위 코드에서 startproject는 Django 프로젝트의 기반 구조를 만드는 기능이다.
(오류) django-admin 모듈을 찾지 못할 경우, django-admin 별도 설치 진행
pip install django-admin
# 파일명 urls.py
from django.contrib import admin
from django.urls import path
from ninja import NinjaAPI
api = NinjaAPI()
@api.get("/add")
def add(request, a: int, b: int):
return {"result": a + b}
urlpatterns = [
path('admin/', admin.site.urls),
path("api/", api.urls),
]
python3 ./manage.py runserver
(주의) 마이그레이션 미적용
장고에서 마이그레이션을 진행하지 않았을 경우, 발생하는 오류이다.
장고는 ORM을 사용하기에 models.py와 클래스를 통해 DB 스키마를 생성하고 컨트롤하는데, 모델의 변경 내역을 DB 스키마에 적용시키지 않았을 때 위와 같은 오류가 발생합니다. 관련 블로그 글
python3 ./manage.py migrate
마이그레이션 명령어를 실행하면, 스키마에 적용되며 해당 오류가 발생하지 않습니다.
접속 URL: http://localhost:8000/api/add?a=1&b=2
결과: {"result": 3}
장고 닌자에서는 기본적으로 Swagger UI와 Redoc으로 API 문서화를 지원한다.
접속 URL: http://127.0.0.1:8000/api/docs
단, 기본 설정이 Swagger UI이므로 Redoc으로 수정하고자 한다면 하단의 방식으로 코드를 설정해야 한다.
api = NinjaAPI(docs=Redoc())
from ninja import NinjaAPI
api = NinjaAPI()
@api.get("/hello")
def hello(request):
return "Hello World"
from django.contrib import admin
from django.urls import path
from .api import api
urlpatterns = [
path('admin/', admin.site.urls),
path("api/", api.urls),
]
레퍼런스