django와 백엔드에 대한 이해: 입문자의 입장에서

mynghn·2022년 7월 6일
4

🎯 이 글의 목적: 백엔드 프로젝트 개발 전에 쟝고 탑다운 정리 + 웹 서비스에서 백엔드의 역할 짚고 넘어가기

🖼️ django의 Model View Template(MVT) 패턴

(from MDN web docs)

쟝고의 기본 서비스 아키텍쳐. 웹 애플리케이션 프레임워크에서 주로 차용하는 Model-View-Controller(MVC) 소프트웨어 디자인 패턴의 일종이라고 볼 수 있음.

MVC 패턴은
앱을 구성하는 데이터를 담당하는 Model
유저에게 데이터를 보여주는 방식을 담당하는 View
유저의 입력을 처리하는 로직을 담당하는 Controller
세 가지 구획으로 웹 애플리케이션의 기능을 분류.

그리고 쟝고의 MVT의 경우
Model은 MVC에서와 같은 의미
View가 반대로 MVC의 Controller에 해당하고
MVT의 Template이 MVC의 View에 해당한다고 보면 된다.

  • Model ↔ MVC의 Model
  • View ↔ MVC의 Controller
  • Template ↔ MVC의 View

쟝고의 Model, View, Template 레이어가 각각의 역할을 하면서 상호작용하는 웹 서비스의 기본적인 작동 과정은 다음과 같다.

🎬 django 웹 서비스 기본 시나리오

  1. 유저(클라이언트/웹브라우저)가 서버로 HTTP 요청 전송
  2. 이를 django의 URL dispatcher가 받아 담당 View function으로 routing
  3. View function은 사전 정의된 로직에 따라 들어온 요청을 처리
  4. 그 과정에서 Model의 애플리케이션 데이터를 create/read/update/delete
  5. 요청 처리 결과를 Template에 담아 render
  6. render된 결과를 HTTP 응답의 형태로 View가 반환. 이를 유저에게 다시 제공.

위의 흐름을 요약하면

데이터(Model)로직(View)에 따라 처리해 유저에게 보여준다(Template)

는 것이고, 이러한 웹 서비스의 본질을 세 가지 핵심적인 요소로 나누어 구조적으로 이해하고 관리하겠다는 것이 쟝고의 MVT 패턴이다.

Models

  • 웹 서비스가 반복적으로 저장하고 활용할 데이터의 구조를 파이썬 클래스로 표현할 수 있도록 쟝고에서 제공하는 API
    • 모든 모델 클래스는 django.db.models.Model의 subclass로 구현
    • 개발 과정에서 구현한 모델 클래스는 작성한 대로 기능하는 일종의 DB 접근 API
    • Model API 용례
      • Views 레이어의 로직 안에서 모델 데이터 조작에 활용
      • 쟝고 쉘에서 interactive하게 모델 inspect
  • ORM 기능 수행
    • 하나의 모델 클래스는 하나의 DB 테이블과 대응
    • 모델 클래스의 모든 어트리뷰트는 각각 DB 필드가 됨.
    • 모델의 구현 사항 변경 내역을 반영해 DB 스키마를 변경시키는 migration 기능 제공

Views

  • 유저의 HTTP 요청을 받아 내부적으로 처리 후, 다시 HTTP 응답을 돌려주기까지의 로직을 담당
  • 크게 두 가지 파트로 구성
    1. 요청의 URL을 보고 대응하는 파이썬 함수로 routing하는 URL dispatcher
    2. URL dispatcher를 거쳐 넘어온 요청을 처리하는 파이썬 함수들(View function)
  • URL dispatcher는 특정 파이썬 모듈(URLconf)에 정의된 대로 작동
    • 쟝고는 해당 파일에서 urlpatterns라는 변수 이름을 가진 리스트를 탐색
    • 요청 URL이 들어오면, 해당 리스트에 순서대로 정의된 패턴 중 가장 먼저 매치된 패턴에 따라 요청이 매핑된 View function으로 routing
  • View function은 들어온 HTTP 요청을 기반으로 모델에 들어있는 데이터를 조회하고 필요 시 가공해 그 결과를 유저에게 HTTP 응답의 형태로 다시 전달
  • View function 호출 시 위치 인자
    • 첫 번째로 쟝고의 HttpRequest 객체
    • 두 번째부터는 URLconf에 패턴 정의한 대로 요청 URL로부터 capture된 문자열들 → 함수 내부에서 사용할 인자를 유저가 요청 URL에 포함하도록 할 수 있음
  • View function의 리턴 타입은 반드시 HttpResponse 객체
  • View는 단일 파이썬 함수로 된 Function Based View(FBV)와 쟝고에서 추상화하여 제공하는 클래스 인터페이스들을 상속받아 활용할 수 있는 파이썬 클래스 기반의 Class Based View(CBV)가 있음
    • CBV의 경우 실제 URL dispatcher를 거쳐 호출되는 건 as_view() 클래스 메소드를 통해 생성된 파이썬 함수 형태의 호출 가능한 객체

Templates

  • 쟝고에서 HTTP 요청의 처리 결과를 유저에게 보여줄 형태(주로 HTML 문서로 표현된 웹페이지)로 가공하는 Template 레이어
  • 요청 처리 결과에 따라 바뀌는 동적인 부분과 바뀌지 않는 정적인 부분을 구분해서 Django template을 미리 작성해두고, 유저에게 보여줄 때는 동적 부분을 알맞게 채워넣어 최종 문서를 렌더링
    • Django template은 문서 파일 혹은 파이썬 문자열의 형태
    • Django template에서 동적으로 처리할 부분은 Django template language(DTL)를 사용해 표현
    • 동적 부분에 명시된 DTL 문법에 따라 요청 처리 결과를 가공해 채워넣는 방식

+ 그리고 django에서 중요한 것들

Forms

  • 일단 웹 서비스는 화면을 통해 유저로부터 다양한 형태의 입력을 받을 필요가 있음(회원가입, 로그인, 검색 등)
  • 따라서 HTML에는 해당 기능을 위한 <form>...</form> 태그가 있음 (HTML Form)
    • form 태그 아래에서 입력이 어떤 타입의 데이터인지, 어떤 HTTP 메소드를 사용할지, 입력 데이터를 보낼 URL 등을 결정
    • form을 통해 선택 가능한 HTTP 메소드는 시스템의 상태를 바꾸는 POST, 조회 목적의 GET 두 개
  • 정리하자면 HTML Form은 유저가 GUI(웹 화면)를 통해 특정한 형태의 HTTP 요청을 서버에 쉽게 보낼 수 있도록 도와줌
  • 쟝고의 Form은…
    • 입력을 위한 HTML Form을 자동으로 생성
    • 입력 값에 대한 유효성 검증 수행 (Validation)
  • 쟝고의 기본 Form 클래스를 상속받아 커스텀 클래스를 정의하고 이를 View function 안에서 들어온 HTTP 메소드에 따라 분기해서 사용하는 방식
    1. GET 요청으로 URL 접근 시 HTML Form 생성해서 그려주고
    2. POST 요청으로 입력 데이터 넘겼을 시 처리해서 결과 보여주는 방식
  • 유효성 검증 완료된 값은 Form 객체 안의 딕셔너리 타입 cleaned_data 어트리뷰트를 통해 접근 가능

django-admin & manage.py

  • django-admin: 쟝고의 프로젝트 관리용 CLI 도구
  • manage.py
    • 쟝고 프로젝트 생성 시 아래에 자동으로 생성되는 파이썬 모듈
    • django-admin과 같은 역할을 하고 그에 더해 프로젝트 내부에서 사용할 설정 파일을 지정하는 DJANGO_SETTINGS_MODULE 환경변수 세팅까지 함
    • 프로젝트의 설정 파일 지정까지 하기 때문에 하나의 쟝고 프로젝트에서 작업할 땐 manage.py 사용 권장
  • 기본 용법
        $ django-admin <command> [options]
        $ manage.py <command> [options]
        $ python -m django <command> [options]
  • 주요 작업
    • 모델 migration
      1. 모델 코드 수정
      2. migration 파일 생성
        django-admin makemigrations <app_name>
      3. DB에 migrate
        django-admin migrate <app_name> <migration_name>
    • 서버 실행
      django-admin runserver [addrport]
      ex) django-admin runserver localhost:8000
    • 쟝고 쉘 실행
      django-admin shell --interface {ipython,bpython,python}
      현재 쟝고 프로젝트 내부에서 작업할 수 있는 대화형 파이썬 쉘을 여는 명령
    • 쟝고 프로젝트 생성
      django-admin startproject name [directory]
      디렉토리 아래에 manage.py 모듈과 프로젝트 패키지(기본 설정 파일인 settings.py 포함)가 생성됨
    • 쟝고 앱 생성
      django-admin startapp name [directory]
      반복되는 기능을 모아 정의할 수 있는 최소 단위의 쟝고 앱 패키지를 생성하는 명령
      디렉토리 아래에 빈 models.py를 포함해 쟝고 앱을 제작할 수 있는 기본 얼개가 만들어짐
    • superuser 생성
      django-admin createsuperuser
      is_staff 속성이 True인 admin 사이트에 접근할 수 있는 관리자 계정을 만드는 명령

Settings

  • 쟝고에서는 프로젝트와 관련된 다양한 설정 사항을 파이썬 모듈에 기록해 관리
  • 터미널의 DJANGO_SETTINGS_MODULE 환경변수로 어떤 파이썬 모듈을 설정 파일로 사용할지 지정
    • django-admin runserver 명령 시 --settings 옵션을 통해서도 파이썬 모듈 경로 전달 가능
  • 주요 설정 변수
    • INSTALLED_APPS
      • 해당 쟝고 프로젝트에서 사용하는 쟝고 앱을 모두 나열한 리스트
      • 서드파티 앱을 설치하거나 앱을 직접 구현했을 때 추가해줘야 함
    • ALLOWED_HOSTS
      • 해당 쟝고 프로젝트가 요청을 받고 응답을 보낼 수 있는 호스트/도메인 whitelist
      • 요청을 보내는 프론트엔드가 따로 있고 별도의 호스트/도메인으로 서빙 중일 경우 여기에 명시해줘야 함
    • AUTH_USER_MODEL
      • 프로젝트 내부에서 사용자 인증에 사용할 User 모델 클래스를 명시
      • 기본값은 [auth.User](https://docs.djangoproject.com/en/4.0/ref/contrib/auth/#user-model)
      • 프로젝트 생성과 함께 django.contrib.auth.models.AbstractUser 를 상속받아 커스텀 User 모델을 만들고, 가장 처음 migration에서 해당 User 모델을 반영하는 것을 권장 → 이후 필요에 따라 모델 수정
    • DEBUG
      • 디버그 모드 사용 여부를 나타내는 boolean 변수
      • 배포 시에는 False로 꺼서 나가야 함
    • MEDIA_ROOT
      • 모델 클래스의 FileField/ImageField를 통해 저장한 모든 파일은 Media 파일로 취급
      • Media 파일의 경우 DB 필드에는 저장경로(문자열)를 저장하고 파일 원본은 파일 스토리지에 저장
      • 파일 스토리지의 저장 위치는 설정 파일에 정의한 MEDIA_ROOT 변수 값
    • MEDIA_URL
      • MEDIA_ROOT에 있는 Media 파일에 접근할 때 사용할 수 있는 URL
      • Django Template에서 {{ MEDIA_URL }}과 같이 사용 가능
    • STATIC_ROOT
      • 배포 시 프로젝트 내부 Static 파일을 django-admin collectstatic 명령으로 모을 때 사용할 경로
    • STATIC_URL
      • STATIC_ROOT에 있는 Static 파일에 접근할 때 사용할 수 있는 URL

Admin 사이트

  • 쟝고의 Model 중심 자동 어드민 인터페이스
  • 별도의 화면 설계 없이 쟝고에서 제공하는 admin 사이트를 통해 내부 Model 관리를 할 수 있음
  • 기본 설정된 /admin/ URL로 admin 사이트 접근 가능
  • 기본 용법
    별도 admin.py 모듈에 admin 사이트를 통해 관리하고 싶은 모델에 대해 아래와 같이 선언
    from django.contrib import admin
    from .models import MyModel
    
    @admin.register(MyModel)
    class MyModelAdmin(admin.ModelAdmin):
        pass

Django REST Framework (DRF)

  • 쟝고를 사용해 RESTful API 서버를 쉽게 만들 수 있게 도와주는 서드파티 라이브러리
  • 통합 웹 프레임워크로서 Template 레이어를 활용해 화면까지 구성하는 기본 쟝고와 달리 프론트엔드를 별도로 구성하는 경우 주로 사용 (SPA, 모바일 앱을 따로 개발하는 경우)
  • 완성된 화면까지 그리는 대신, 화면을 그리는 데에 필요한 데이터의 형태까지만 만들어서 프론트엔드에 던져 주는 방식
  • 주요 기능
    • Serializer를 통한 입력 데이터 검증 및 응답 데이터 직렬화
    • APIView/ViewSet을 활용한 View 레이어의 요청 처리 로직 담당
    • 다양한 Renderer 클래스를 활용한 JSON 포함 다양한 응답 포맷 지원
    • 인증(Authentication)과 권한(Permission) 체계 → 서드파티를 통해 JWT 지원
    • 설계한 API 서버에 맞춰 웹 화면을 자동 생성해 Web browsable API 구현
  • 기본 쟝고의 MVT 아키텍쳐에서 Model만 남겨두고 나머지 레이어를 새로운 방식으로 대체한다고 볼 수 있음

💡 이제 django를 활용해서 백엔드를 만들어볼 차례

🤚 그 전에, 웹 서비스와 백엔드에 대한 이해

쟝고를 활용해 무언가 만들어 보기 전에, 먼저 문제를 명확히 해보자.

우선 지금까지 쟝고를 배운 것은 파이썬을 이용한 백엔드 작업을 하기 위해서.
Template 레이어가 있는 쟝고는 프론트엔드까지 한번에 해결할 수 있는 통합 웹 프레임워크지만 주요 사용 목적은 백엔드를 구축하기 위함.

하지만 백엔드만 가지고는 추상적인 구현일 뿐 애플리케이션 관점에서 완결된 작업이 될 수 없음. 일반 유저가 사용할 수 있는 형태로 존재하는 하나의 웹 서비스가 유효한 프로젝트의 단위일 것.

그렇다면 현재의 웹 서비스 패러다임에서 백엔드와 프론트엔드 구분에 대해 생각해보자.
즉, 웹 서비스를 만들어야 하는데 백엔드가 꼭 필요한가?

MVC 패턴을 가지고 생각해봤을 때,
보통의 유저가 사용할 웹 서비스를 만든다고 하면 애플리케이션 관점에서는 오히려 사용자가 상호작용할 인터페이스(View)와 사용자가 원하는 기능을 수행해 줄 로직(Controller)이 만들고자 하는 웹서비스의 필수적인 요소이지 않을까?

그리고 자바스크립트 덕분에 어떤 프론트엔드를 만든다고 해도 로직은 기본적으로 심을 수 있을 것.

따라서 로직 쪽에서 임무의 중복이 있지만 간단한 수준의 경우 이를 프론트엔드에 양보한다고 하면,
Model 레이어의 관리가 주 임무인 백엔드는 웹 서비스에 있어 필수가 아닌 선택이 된다. (심지어 간단한 수준의 데이터 저장은 프론트엔드 사이드에서도 수행이 가능하다)

여기 깃헙 레포에 가면 프론트엔드만으로 완성 가능한 웹 애플리케이션의 예시가 여럿 있다. 간단한 입력을 받아 일련의 로직을 거친 뒤 결과 값을 유저에게 보여주는 서비스.

그래서 백엔드 프로젝트를 진행하고자 한다면 그냥 웹 서비스가 아닌 백엔드가 활약할 수 있는 웹 서비스를 만들어야 하겠다.

그런 서비스는 당연히 Model 레이어가 필수로 있어야 하는, 데이터 활용이 복잡한 서비스일 것이고 아래와 같은 특징이 있을 것 같다.

  • 유저별로 할당된 데이터를 나눠 구분해야 하는 서비스
  • 유저로부터 입력 받은 데이터를 저장해 계속 기억해야 하는 서비스
  • 유저의 데이터를 가지고 수행해야 하는 로직(계산)이 복잡한 서비스

기업이 서비스할 정도의 규모가 있는 서비스는 대부분 백엔드가 당연히 필요하다. 위의 레포에서도 티어가 올라가 서비스가 복잡해지면 백엔드가 필요한 서비스가 된다.

하지만 시작하는 입장에서 생각해보면 막연하게 들어본 대로 백엔드와 프론트엔드는 웹 서비스에 있어 당연하게 그냥 있어야 하는 거라고 받아들이기 쉬움

역할과 필요성을 먼저 알고 만들기 위해 다소 당연한 얘기를 파고 들어 정리해봤는데
이제 실제로 웹 서비스를 한 번 만들어보자.

0개의 댓글