장고(Django)는 고급 파이썬 프레임워크입니다. 이는 강력한 웹 애플리케이션을 구축하는 데 있어 단순성과 효율성으로 인기를 끌고 있습니다.

장고 아키텍처의 핵심은 모델-뷰-템플릿(MVT) 패턴입니다. 모델, 뷰, 템플릿이 어떻게 상호작용하는지 잘 이해하는 것은 장고의 모든 기능을 활용하고자 할 때 매우 중요합니다.

장고에 완전히 새로운 사용자이거나 초보자라면, 이 글은 이러한 구성 요소가 어떻게 작동하고 서로 상호작용하여 동적인 웹 애플리케이션을 만드는지를 보여주는 포괄적인 가이드가 될 것입니다.

더욱 이해하기 쉽게, 우리는 이 구성 요소들의 상호 연결성을 더 잘 이해할 수 있도록 간단한 애플리케이션을 구축할 것입니다.

벌써 흥미진진하다면, 바로 시작해봅시다!

우리가 다룰 내용은 다음과 같습니다:

전제 조건

따라가기 위해 필요한 것:

  • 웹 애플리케이션이 작동하는 방식에 대한 기본적인 이해, 클라이언트-서버 아키텍처 포함.

  • Python에 대한 기본 지식.

MVT 아키텍처란 무엇인가요?

MVT 패턴은 Django의 웹 애플리케이션의 코드베이스 및 워크플로우를 구성하는 방법입니다. 이 아키텍처를 구성하는 구성 요소는 모델(Model), 뷰(View) 및 템플릿(Template)입니다. 각 구성 요소는 특정 기능을 수행한 다음 다른 구성 요소에게 작업을 전달합니다.

구성 요소와 그들이 수행하는 특정 기능을 간단히 살펴보겠습니다:

  • 모델(Model): 데이터 레이어로도 알려져 있으며 데이터를 관리하고 데이터베이스와 상호 작용합니다.

  • 뷰(View): 로직 레이어로도 알려져 있으며 중개자 역할을 하고 로직을 처리하며 데이터 흐름을 관리합니다.

  • 템플릿(Template): 프레젠테이션 레이어로도 알려져 있으며 사용자 인터페이스에 HTML 콘텐츠를 렌더링합니다.

이제 Django 애플리케이션에서 구성 요소와 역할에 대한 개략적인 이해를 갖게 되었으므로, 각 구성 요소가 아키텍처에서 상호 작용하는 방식을 상세히 살펴보겠습니다.

모델 구성요소

모델은 Django 애플리케이션 내에서 데이터의 구조와 상호 작용을 관리하며, 데이터의 중요한 역할로 인해 Django 앱의 기초가 됩니다.

Django 모델은 관계형 데이터베이스와 Python 코드 간의 간극을 메우는 강력한 기능인 객체-관계 매핑(ORM)을 활용합니다. 이는 Python 객체(클래스)를 데이터베이스 테이블로 변환하고, 그 속성을 열로, 인스턴스를 테이블 내의 행으로 변환합니다.

ORM의 큰 장점 중 하나는 SQL 쿼리를 작성하는 대신 Python 객체를 사용하여 데이터베이스와 상호작용할 수 있다는 점입니다. 이를 이해할 수 있도록 다른 언어로 변환하는 번역가로 생각할 수 있습니다. 이 경우 ORM은 Python 코드를 데이터베이스가 실행할 수 있는 SQL 명령으로 변환하며, 그 반대도 가능합니다.

Django 모델은 모든 데이터베이스 관련 논리를 캡슐화하고 데이터베이스의 구조를 정의하여, 저장하고자 하는 데이터의 청사진 역할을 합니다.

Django 모델의 일반 형식

Django에서는 모든 모델이 특정한 선언 방식을 따릅니다. 다음은 모델 선언의 기본 구조입니다:

class <model_name>(models.Model):
    <field_name> = models.<field_type>(<optional_field_characteristics>)

이제 이를 분해해 보겠습니다:

  • class: Django에서 모델을 정의하는 데 사용되는 키워드입니다.

  • model_name: 모델의 이름입니다.

  • models.Model: 모델 클래스가 상속하는 기본 클래스입니다.

  • field_name: 데이터베이스 열의 이름입니다.

  • field_type: 필드가 보유한 데이터 유형을 나타내며 charField, BooleanField 등이 있습니다.

  • optional_field_characteristics: 필드 동작을 추가로 정의하는 데 사용되며 max_length, default 등이 있습니다.

모델 예시

지금까지 모델에 대해 알아왔으니, 작업 목록을 위한 하나를 구성할 것입니다. 일반적으로 작업 제목, 설명 및 작업이 완료되었는지 여부를 나타내는 표시가 포함됩니다.

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

이 모델에서:

  • Task는 모델의 이름입니다.

  • 작업 모델에는 세 가지 필드가 있습니다:

    • title: 최대 100자의 텍스트를 보유하는 CharField입니다.

    • description: 더 긴 텍스트를 위한 TextField입니다.

    • completed: 기본값이 FalseTrue 또는 False 값을 저장하는 BooleanField입니다.

뷰 구성요소

Django 뷰는 사용자 요청을 처리하고 응답을 반환하는 역할을 합니다. 이들은 모델과 템플릿 사이의 다리 역할을 하며 모델 객체에서 데이터를 수집하고 해당 데이터에 대한 논리적 작업(특정 기준에 따른 쿼리와 같은)을 수행한 후 데이터를 템플릿에 표시하기 위해 전달합니다.

뷰는 애플리케이션의 복잡성과 요구 사항에 따라 함수 또는 클래스 기반으로 작성될 수 있습니다.

Django 뷰의 일반적인 형식

다음은 뷰의 기본 구조입니다:

def <view_name>(request):
    # 뷰 로직이 여기에 들어갑니다....
    return render(request, <template>, <context>)

세부적으로 살펴보겠습니다:

  • view_name: 뷰 함수의 이름입니다.

  • request: 클라이언트가 Django 서버에 보낸 HTTP 요청으로, 폼 제출이나 버튼 클릭을 통해 트리거될 수 있습니다.

  • return render: HTML 응답을 생성하는 데 사용됩니다. 다음을 포함합니다:

    • request: 수신된 요청에 관한 정보를 포함하는 요청 객체입니다.

    • template: 렌더링할 템플릿 파일입니다.

    • context: 템플릿에서 사용 가능한 변수를 포함하며, 일반적으로 딕셔너리 형식으로 제공됩니다.

예제 보기

작업 목록을 계속 진행하면서, 우리의 뷰는 다음과 같이 보일 것입니다:

def task_list(request):
    # 로직이 여기 들어갑니다...
    return render(request, <template>, {'tasks': tasks})

템플릿 컴포넌트

Django 템플릿은 브라우저에서 최종 HTML 출력을 렌더링하는 역할을 합니다. 데이터가 어떻게 표현되어야 하는지를 정의하며, HTML과 Django의 템플릿 언어의 조합을 사용합니다.

Django 템플릿 언어는 템플릿 태그 {% %}템플릿 변수 {{ }}를 사용하여 HTML 템플릿에서 Django 모드로 들어갈 수 있도록 합니다. 이 모드에서는 뷰에서 정의된 변수에 접근하고 템플릿 내에서 제어 구조를 사용할 수 있습니다.

템플릿은 CSS 또는 선호하는 CSS 프레임워크를 사용하여 스타일을 적용하여 사용자 인터페이스를 더 보기 좋게 만들 수 있습니다.

템플릿 예제

우리의 템플릿은 Django의 템플릿 언어가 적용된 일반 HTML 파일입니다. 우리의 작업 목록 템플릿은 다음과 같이 보일 것입니다:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>
</body>
</html>

이 템플릿에서:

  • for 루프는 tasks 목록의 각 작업을 반복합니다(이 목록은 뷰에서 컨텍스트로 전달되었음을 기억하세요).

  • 각 작업에 대해 작업의 titlecompleted 상태(“완료” 또는 “미완료”)를 출력합니다.

  • 만약 tasks 리스트가 비어 있다면, {% empty %} 블록은 “사용 가능한 작업이 없습니다.”라는 대체 메시지를 표시합니다.

MVT 워크플로우를 나타내는 다이어그램

이 다이어그램은 Django의 MVT 아키텍처 내에서 데이터가 흐르는 방식을 나타냅니다:

MVT의 실제 비유

당신이 레스토랑에 가서 좋아하는 식사를 주문한다고 상상해보세요. 그 뒤에서 레스토랑은 각 요리가 어떻게 준비되어야 하는지를 설명하는 요리책을 가지고 있습니다. 셰프는 레시피를 사용하여 당신이 주문한 대로 정확하게 식사를 준비합니다. 준비가 끝나면, 서버가 식사를 멋지게 당신에게 제공합니다.

셰프가 요리를 만들기 위해 레시피를 따르는 것처럼, 뷰는 모델을 사용하여 데이터를 수집하고 처리합니다. 마지막으로, 서버가 요리를 배달하는 것과 같이, 템플릿은 최종 출력을 사용자에게 명확하고 매력적인 형식으로 제공하는 것을 보장합니다.

모든 것을 프로젝트로 통합하기

이 섹션에서는 시작부터 끝까지 기사를 예로 들어 사용한 작업 목록을 설정하는 방법을 안내합니다. 마지막에는 MVT 아키텍처가 완전히 작동하는 기능적인 애플리케이션을 갖게 될 것입니다.

파이썬 설치하기

먼저, 파이썬이 설치되어 있는지 확인하세요. 최신 파이썬 버전을 다운로드하려면 파이썬 공식 웹사이트를 방문하세요.

장고 프로젝트 및 앱 설정하기

다음으로 장고를 설치합니다. pip를 사용하여 설치할 수 있습니다:

pip install django

폴더를 만들고 좋아하는 코드 편집기에서 엽니다.

터미널에서 다음 명령을 차례로 실행하여 새 장고 프로젝트와 앱을 만듭니다:

django-admin startproject myproject 
cd myproject
django-admin startapp myapp

모델 정의하기

귀하의 myapp/models.py에서:

from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

폼 만들기

작업 모델을 기반으로 한 장고 폼이 필요하므로 장고 ModelForm을 사용하여 하나를 생성합니다.

귀하의 myapp에서 forms.py라는 이름의 파일을 만들고 다음 코드를 삽입합니다:

from django import forms
from .models import Task

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['title', 'description', 'completed']

이 코드에서:

  • Task.models에서 가져옵니다.

  • class TaskForm(forms.ModelForm): 이것은 TaskForm이라는 새로운 클래스를 생성하는데, 이는 forms.ModelForm의 하위 클래스입니다.

  • class Meta:: 장고의 ModelForm에서 사용되는 특별한 클래스로, 폼을 구성하는 설정을 제공합니다. Meta 클래스는 연관된 모델 및 폼에 포함시킬 필드를 지정하여 폼을 생성하는 방법을 장고에 알려줍니다.

  • model = Task: 폼이 기반으로 하는 모델을 지정합니다. 이 경우, 폼은 Task 모델을 기반으로 합니다.

  • fields = ['title', 'description', 'completed']: Task 모델에서 폼에 포함해야 하는 필드를 지정합니다. 이를 통해 모델 필드 중 어떤 것이 폼에 나타날지를 제어할 수 있으며, 모든 필드가 아닌 특정 필드만 포함하도록 사용자 정의할 수 있습니다.

뷰(View) 생성

당신의 myapp/views.py에 이 코드를 삽입하세요:

from django.shortcuts import render,redirect
from .models import Task
from .forms import TaskForm

def task_list(request):
    tasks = Task.objects.all()    # 모든 작업 검색

    if request.method == 'POST':    # 폼 제출 처리
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('task_list')  # 중복 제출 방지를 위한 리다이렉트
    else:
        form = TaskForm()

    # 작업과 폼을 템플릿에 전달
    return render(request, 'task_list.html', {'tasks': tasks, 'form': form})

이 보기에서,

  • TaskFormforms에서 가져옵니다.

  • 코드는 요청 메서드가 POST인지 확인하여 사용자가 폼을 제출했음을 나타냅니다.

  • 메서드가 POST인 경우, 제출된 데이터(request.POST)를 사용하여 TaskForm의 인스턴스를 생성합니다.

  • 그 후, form.is_valid()를 사용하여 폼을 검증하고, 유효한 경우 데이터베이스에 저장됩니다.

  • 저장 후, 사용자는 중복 제출을 방지하기 위해 작업 목록 페이지로 리디렉션됩니다.

템플릿 정의

귀하의 myapp 디렉토리에서 templates 폴더를 만드세요. 템플릿 폴더 안에 파일을 생성하고 이름을 task_list.html로 지정합니다. 사용자 입력을 수집하고 UI에 목록으로 표시하는 폼 요소를 추가해야 합니다.

task_list HTML 파일에는:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>

    <h2>Add a New Task</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Add Task</button>
    </form>
</body>
</html>

추가된 폼 코드에서는:

  • 데이터 제출을 위한 POST 방식의 HTML 폼을 생성했습니다. CSRF 공격으로부터 보호하기 위해 {% csrf_token %}을 포함하고 있습니다.

  • 폼 필드는 {{ form.as_p }}를 사용하여 렌더링되며, 각 필드는 <p> 태그 내에 표시됩니다.

  • 마지막으로 “작업 추가”라는 레이블이 붙은 제출 버튼이 제공되어 사용자가 폼 데이터를 제출할 수 있습니다.

폴더 구조

이 지점에 도달했을 때, 앱을 올바른 방법으로 구성하고 있는지 꼼꼼히 확인하는 것이 중요합니다. 폴더/파일 구조는 다음과 같아야 합니다:

└── 📁myproject
    └── 📁myapp
        └── 📁__pycache__
        └── 📁migrations
        └── 📁templates
            └── task_list.html
        └── __init__.py
        └── admin.py
        └── apps.py
        └── forms.py
        └── models.py
        └── tests.py
        └── urls.py
        └── views.py
    └── 📁myproject
        └── 📁__pycache__
        └── __init__.py
        └── asgi.py
        └── settings.py
        └── urls.py
        └── wsgi.py
    └── db.sqlite3
    └── manage.py

프로젝트의 URL 구성

myproject/urls.py에서 myapp의 URL을 포함하세요:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),
]

앱을 프로젝트 설정에 추가

myproject/settings.py에서 myapp설치된 앱 목록에 추가하세요:

INSTALLED_APPS = [
    'myapp',      # myapp 앱을 추가했습니다
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

서버 실행

마이그레이션을 적용하고 서버를 실행하려면 다음 명령어를 입력하세요:

python manage.py migrate

python manage.py runserver

브라우저에서 http://127.0.0.1:8000/를 방문하여 앱을 테스트하세요.

최종 결과

작업 목록 앱이 폼을 사용하여 몇 가지 작업을 추가한 후 브라우저에서 어떻게 보이는지 확인할 수 있습니다. 템플릿 스타일링을 원하는 대로 추가로 개선할 수 있습니다.

결론

이 글에서는 Django의 MVT 아키텍처의 구성 요소, 서로 상호 작용하는 방법, 웹 경험을 어떻게 매끄럽게 만드는지에 대해 배웠습니다. 우리는 또한 어떻게 실제로 작동하는지 간단한 프로젝트를 만들어 보았으며, 이제 더 잘 이해하고 있기를 바랍니다.

만약 이 기사를 즐겁게 읽었다면, 더 많은 프로그래밍 기사와 포스트를 보려면 X에서 저를 팔로우하거나 LinkedIn에서 저와 연락할 수 있습니다.

다음에 뵙겠습니다!