[개발] Django를 활용한 웹 서버 구축 방법

Django 소개

Django는 파이썬 기반의 웹 프레임워크로, 웹 애플리케이션 개발을 빠르고 효율적으로 할 수 있게 도와줍니다.

장고의 주요 특징

– 강력한 ORM(Object-Relational Mapping)을 제공하여 데이터베이스 작업을 간소화합니다.
– MTV(Model-Template-View) 아키텍처를 지원하여 애플리케이션의 구조를 명확하게 구분할 수 있습니다.
– 내장된 폼 처리 및 유효성 검사 기능을 제공하여 사용자 입력을 손쉽게 처리할 수 있습니다.
– 간편한 URL 패턴 설정으로 세부 뷰 관리를 용이하게 합니다.
– 사용자 인증과 권한 관리를 미리 구현하여 보안을 강화합니다.
– 다양한 확장 기능과 패키지를 제공하여 개발 생산성을 크게 향상시킵니다.


# Django 설치 확인
import django
print(django.get_version())

Django 프로젝트 생성하기

Django 프로젝트를 생성하려면 아래의 단계를 따르면 됩니다.

단계 1: 가상 환경 설정


# 가상 환경 생성
python -m venv myenv

# 가상 환경 활성화
source myenv/bin/activate

단계 2: Django 설치


# Django 설치
pip install django

단계 3: Django 프로젝트 생성


# Django 프로젝트 생성
django-admin startproject myproject

프로젝트 생성 후, 프로젝트 디렉토리 안에는 다음과 같은 구조가 생성됩니다:


myproject/
    manage.py
    myproject/
        __init__.py
        settings.py
        urls.py
        ...

단계 4: 서버 실행


# 개발 서버 실행
python manage.py runserver

서버가 실행되면 로컬에서 프로젝트에 접속할 수 있습니다.


Django 앱 생성하기

Django 앱은 프로젝트 안에서 독립적으로 동작하는 기능 단위의 모듈입니다. 앱은 프로젝트 안에서 여러 개 생성할 수 있습니다.

단계 1: 앱 생성


# 앱 생성
python manage.py startapp myapp

앱 생성 후, 앱 디렉토리 안에는 다음과 같은 구조가 생성됩니다:


myapp/
    __init__.py
    admin.py
    apps.py
    models.py
    tests.py
    views.py
    ...

단계 2: 앱 등록

앱을 프로젝트에 등록해야 프로젝트에서 앱을 사용할 수 있습니다. 이를 위해 프로젝트 디렉토리의 `settings.py` 파일에서 `INSTALLED_APPS` 리스트에 앱 이름을 추가합니다.


# settings.py

INSTALLED_APPS = [
    ...
    'myapp',
    ...
]

앱을 등록하면 앱의 모델을 사용하기 위해 데이터베이스 마이그레이션을 수행해야 합니다.

단계 3: 데이터베이스 마이그레이션


# 데이터베이스 마이그레이션
python manage.py makemigrations
python manage.py migrate

앱을 사용할 준비가 완료되었습니다.


Django 모델 정의하기

Django 모델은 데이터베이스의 테이블을 정의하는 역할을 합니다. 각각의 모델은 데이터베이스의 테이블로 매핑되어 데이터를 저장하고 조회할 수 있게 해줍니다.

단계 1: 모델 정의

Django 모델은 `models.py` 파일에 정의됩니다. 각 필드는 데이터베이스의 열로 매핑되며, 여러 종류의 필드를 사용할 수 있습니다. 예시로 `CharField`, `IntegerField`, `DateField` 등이 있습니다.


from django.db import models

class MyModel(models.Model):
    field1 = models.CharField(max_length=100)
    field2 = models.IntegerField()
    field3 = models.DateField()
    ...

단계 2: 모델 마이그레이션

모델의 변경 사항을 데이터베이스에 반영하기 위해 마이그레이션을 수행해야 합니다.


# 모델 마이그레이션 생성
python manage.py makemigrations

# 데이터베이스 마이그레이션
python manage.py migrate

모델 정의와 데이터베이스 마이그레이션을 통해 모델을 사용할 준비가 완료됩니다.


Django 데이터베이스 마이그레이션

Django의 데이터베이스 마이그레이션은 모델의 변경 사항을 데이터베이스에 반영하는 프로세스입니다. 마이그레이션은 데이터베이스 테이블의 생성, 수정, 삭제 등을 처리합니다.

단계 1: 마이그레이션 파일 생성

모델을 변경한 후에는 해당 변경 사항을 마이그레이션 파일로 생성해야 합니다. 마이그레이션 파일은 변경 사항을 기록한 Python 스크립트입니다.


# 마이그레이션 파일 생성
python manage.py makemigrations

위 명령을 실행하면 마이그레이션 폴더에 새로운 마이그레이션 파일이 생성됩니다.

단계 2: 데이터베이스 마이그레이션

마이그레이션 파일을 생성한 후, 변경 사항을 실제 데이터베이스에 적용해야 합니다.


# 데이터베이스 마이그레이션
python manage.py migrate

위 명령을 실행하면 Django는 마이그레이션 파일을 기반으로 데이터베이스의 상태를 업데이트합니다.

추가 기능

– 마이그레이션 내역 확인: `python manage.py showmigrations`
– 특정 앱의 마이그레이션 취소: `python manage.py migrate myapp zero`
– 특정 마이그레이션 취소: `python manage.py migrate myapp `
– 초기 마이그레이션 생성: `python manage.py makemigrations –empty myapp`


Django 뷰와 템플릿

Django의 뷰와 템플릿은 웹 애플리케이션에서 사용자에게 보여지는 화면을 생성하는 데 사용됩니다. 뷰는 요청을 처리하고, 템플릿은 HTML 페이지의 구조와 내용을 정의합니다.

뷰(View)

Django의 뷰는 사용자가 요청한 페이지를 생성하는 역할을 합니다. 뷰는 함수 기반 뷰(Function-based View)와 클래스 기반 뷰(Class-based View)로 구현할 수 있습니다.


from django.shortcuts import render
from django.http import HttpResponse

# 함수 기반 뷰
def my_view(request):
    # 요청을 처리하고 응답 생성
    return HttpResponse("Hello, World!")

# 클래스 기반 뷰
from django.views import View

class MyView(View):
    def get(self, request):
        # GET 요청을 처리하고 응답 생성
        return HttpResponse("Hello, World!")

뷰에서 요청을 처리하여 데이터를 받아 템플릿으로 전달하고, 템플릿에 따라 동적으로 생성된 응답을 반환할 수 있습니다.

템플릿(Template)

Django의 템플릿은 웹 페이지의 구조와 내용을 정의하는 HTML 파일입니다. 템플릿은 정적인 부분과 동적인 부분을 구분하여 작성합니다. 동적인 부분에는 변수, 반복문, 조건문 등을 사용할 수 있습니다.


<!-- 템플릿 예시 -->
<h1>Hello, {{ name }}!</h1>

<ul>
  {% for item in items %}
    <li>{{ item }}</li>
  {% endfor %}
</ul>

위의 템플릿 예시는 `name` 변수를 사용하여 환영 메시지를 출력하고, `items` 리스트를 반복하여 목록을 생성합니다.

뷰와 템플릿 연결

뷰는 템플릿으로부터 받은 동적인 데이터를 처리한 후, `render` 함수를 사용하여 템플릿과 결합하여 최종 응답을 생성합니다.


from django.shortcuts import render

def my_view(request):
    name = "John"
    items = ["apple", "banana", "orange"]
    return render(request, "my_template.html", {"name": name, "items": items})

위의 코드에서 `render` 함수는 `my_template.html` 템플릿을 사용하여 `name`과 `items` 변수를 이용한 동적인 응답을 생성합니다.

추가 기능

– URL 매칭: `urls.py` 파일에서 URL 패턴과 뷰 함수를 연결합니다.
– URL 리버스: URL 패턴의 이름을 사용하여 URL을 동적으로 생성합니다.
– 템플릿 상속: 기본 템플릿을 확장하여 중복 코드를 피하고 모듈화할 수 있습니다.


Django URL 패턴 설정하기

Django의 URL 패턴은 웹 애플리케이션의 URL 경로에 대한 처리 방식을 설정하는 역할을 합니다. URL 패턴 설정은 URLconf 파일을 사용하여 수행됩니다.

URLconf 파일 생성

URL 패턴 설정을 위해 먼저 URLconf 파일을 생성해야 합니다. 일반적으로 `urls.py` 파일이라는 이름으로 생성되며, Django 프로젝트의 최상위 디렉토리에 위치합니다.


# urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('about/', views.about, name='about'),
]

위의 코드는 `urls.py` 파일에 두 개의 URL 패턴을 설정하는 예시입니다. 첫 번째 패턴은 루트 경로에 대한 처리를 담당하고, `index` 뷰 함수를 연결합니다. 두 번째 패턴은 `/about/` 경로에 대한 처리를 담당하고, `about` 뷰 함수를 연결합니다.

URL 패턴 설정

URL 패턴은 `path()` 함수를 사용하여 설정됩니다. 이 함수는 URL 패턴과 처리할 뷰 함수를 연결합니다. 여러 가지 매개변수를 사용하여 패턴을 좀 더 세부적으로 지정할 수 있습니다.


from django.urls import path
from . import views

urlpatterns = [
    path('articles//', views.article_detail, name='article_detail'),
    path('articles///', views.article_detail, name='article_detail'),
]

위의 코드는 URL 패턴에 정수형 매개변수와 슬러그를 사용하는 예시입니다. 동일한 패턴에 대해 서로 다른 처리를 담당하는 뷰 함수를 연결할 수 있습니다.

URL 리버스

URL 리버스는 URL 패턴의 이름을 사용하여 URL을 동적으로 생성하는 기능입니다. URL 패턴에 이름을 지정하면, `reverse()` 함수를 사용하여 URL을 생성할 수 있습니다.


from django.urls import reverse

# URL 리버스
article_detail_url = reverse('article_detail', args=[3, 'hello-world'])
print(article_detail_url)

위의 코드는 `article_detail` 패턴에 대한 URL을 동적으로 생성하는 예시입니다. `reverse()` 함수는 패턴의 이름과 필요한 매개변수 값을 전달하여 URL을 생성합니다.

추가 기능

– 정규 표현식 사용: URL 패턴에 정규 표현식을 사용하여 다양한 패턴을 처리할 수 있습니다.
– include() 함수: 다른 URLconf 파일을 포함하여 URL 패턴을 구성할 수 있습니다.


Django 폼 처리하기

Django의 폼은 사용자로부터 데이터를 입력받고, 데이터의 유효성을 확인하여 처리하는 기능을 제공합니다. 폼 처리를 위해 폼 클래스를 정의하고, 폼 데이터를 저장하고 검증하는 과정이 필요합니다.

폼 클래스 정의

Django에서 폼은 `forms.Form` 클래스를 상속하여 정의합니다. 폼 클래스에는 폼 필드(Field)와 폼 위젯(Widget)을 정의하여 사용자로부터 입력받을 데이터의 타입과 형식을 지정합니다.


from django import forms

class MyForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)

위의 코드는 `MyForm` 클래스를 정의하는 예시입니다. 폼 필드로는 `CharField`와 `EmailField`를 사용하였고, `password` 필드에는 패스워드 입력 위젯(`PasswordInput`)을 지정하였습니다.

폼 데이터 저장

사용자로부터 입력받은 폼 데이터는 `request.POST`를 통해 서버로 전송됩니다. 이 데이터를 폼 객체를 생성하여 저장합니다.


def my_view(request):
    if request.method == 'POST':
        form = MyForm(request.POST)
        if form.is_valid():
            # 폼 데이터 저장
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']
            
            # 데이터 처리 로직
            # ...
    else:
        form = MyForm()
    return render(request, 'my_template.html', {'form': form})

위의 코드는 `my_view` 함수에서 폼 데이터를 받아 저장하는 예시입니다. 폼 객체를 생성할 때 `request.POST`를 전달하여 사용자의 입력 값을 저장합니다. `is_valid()` 메서드는 폼 데이터의 유효성을 확인하며, `cleaned_data`를 통해 유효한 데이터에 접근할 수 있습니다.

폼 데이터 검증

Django의 폼은 자체적으로 데이터 유효성 검사 기능을 제공합니다. 폼 필드에 지정된 검증 규칙을 통해 사용자가 입력한 데이터의 유효성을 검증할 수 있습니다. 검증 규칙을 만족하지 않으면 `is_valid()` 메서드가 `False`를 반환합니다.


from django import forms

class MyForm(forms.Form):
    age = forms.IntegerField(min_value=18, max_value=65)
    agreement = forms.BooleanField(required=True)

위의 코드는 `age` 필드에 대해 최소값과 최대값을 지정하고, `agreement` 필드에 대해 필수 체크 여부를 지정하는 예시입니다. 이러한 검증 규칙을 설정하여 데이터의 일관성과 유효성을 보장할 수 있습니다.


Django 사용자 인증과 권한 관리

Django는 사용자 인증과 권한 관리에 대한 강력한 기능을 제공합니다. 사용자 인증을 통해 웹 애플리케이션의 사용자들을 식별하고, 권한 관리를 통해 특정 사용자에 대한 접근 권한을 제어할 수 있습니다.

사용자 인증

Django는 기본적으로 사용자 인증에 대한 기능을 제공합니다. `authenticate()` 함수를 사용하여 사용자의 신원을 확인하고, `login()` 함수를 사용하여 사용자를 로그인 상태로 변경합니다.


from django.contrib.auth import authenticate, login

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            # 인증 성공, 로그인 처리
            return redirect('dashboard')
        else:
            # 인증 실패
            return redirect('login')
    else:
        return render(request, 'login.html')

위의 코드는 사용자의 로그인을 처리하는 예시입니다. `authenticate()` 함수를 사용하여 제공된 사용자 이름과 비밀번호로 사용자를 인증하고, `login()` 함수를 사용하여 사용자를 로그인 상태로 변경합니다.

사용자 권한 관리

Django는 사용자의 권한 관리를 위해 `groups`와 `permissions`를 사용합니다. `groups`는 관련 있는 권한을 그룹화하는 용도로 사용되고, `permissions`는 개별적인 권한을 지정하는 데 사용됩니다.

사용자를 특정 그룹에 추가하는 방법은 다음과 같습니다.


from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model

User = get_user_model()

def add_user_to_group(user_id, group_name):
    user = User.objects.get(id=user_id)
    group = Group.objects.get(name=group_name)
    user.groups.add(group)

위의 코드는 사용자를 특정 그룹에 추가하는 함수를 보여주는 예시입니다.

특정 그룹에 권한을 추가하는 방법은 다음과 같습니다.


from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType

def add_permission_to_group(group_name, app_label, model, codename):
    content_type = ContentType.objects.get(app_label=app_label, model=model)
    permission = Permission.objects.get(content_type=content_type, codename=codename)
    group = Group.objects.get(name=group_name)
    group.permissions.add(permission)

위의 코드는 특정 그룹에 권한을 추가하는 함수를 보여주는 예시입니다.


Django 프로젝트 배포하기

Django 프로젝트를 개발한 후에는 실제 서비스를 위해 프로젝트를 배포해야 합니다. Django 프로젝트를 배포하기 위해서는 웹 서버와 WSGI 서버를 설정하고, 정적 파일과 데이터베이스 설정을 관리해야 합니다. 아래는 Django 프로젝트를 배포하는 과정을 간략히 설명한 내용입니다.

웹 서버 설정

Django 프로젝트를 배포하기 위해 웹 서버를 설정해야 합니다. 웹 서버는 클라이언트의 요청을 받아 Django 프로젝트로 전달합니다. 대표적으로 Apache, Nginx 등의 웹 서버가 있습니다.

Apache 웹 서버를 사용하는 경우, 다음과 같은 설정을 `httpd.conf` 파일에 추가합니다.


<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    
    DocumentRoot /path/to/project
    
    <Directory /path/to/project>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
    
    WSGIScriptAlias / /path/to/project/wsgi.py
</VirtualHost>

위의 예시에서 `/path/to/project`는 Django 프로젝트의 루트 디렉토리를 나타냅니다. 설정 파일의 내용을 변경한 후 웹 서버를 재시작해야 합니다.

WSGI 서버 설정

Django에서 WSGI(Web Server Gateway Interface) 서버는 웹 서버와 Django 어플리케이션 사이에서 요청과 응답을 중개합니다. 대표적으로 Gunicorn, uWSGI 등의 WSGI 서버가 있습니다.

Gunicorn WSGI 서버를 사용하는 경우, 다음과 같은 명령을 실행하여 설정합니다.


gunicorn myproject.wsgi:application --bind 0.0.0.0:8000

위의 명령을 실행하면 WSGI 서버가 `0.0.0.0:8000`에서 실행되며, Django 프로젝트가 배포됩니다.

정적 파일 설정

Django에서 사용하는 정적(static) 파일은 웹 서버에서 직접 제공하는 것이 좋습니다. 따라서 웹 서버와 Django 프로젝트를 연동하여 정적 파일을 서빙해야 합니다.

Apache 웹 서버를 사용하는 경우, `httpd.conf` 파일에 다음과 같이 설정합니다.


<VirtualHost *:80>
    # ... 이전 설정 ...
    
    <Directory /path/to/project/static>
        Require all granted
    </Directory>
    
    Alias /static /path/to/project/static
    <Directory /path/to/project/static>
        Require all granted
    </Directory>
    
    <Directory /path/to/project/media>
        Require all granted
    </Directory>
    
    Alias /media /path/to/project/media
    <Directory /path/to/project/media>
        Require all granted
    </Directory>
</VirtualHost>

위의 예시에서 `/path/to/project/static`은 Django 프로젝트의 정적 파일 디렉토리를 나타냅니다. 설정 파일의 내용을 변경한 후 웹 서버를 재시작해야 합니다.

데이터베이스 설정

Django 프로젝트를 배포할 때는 데이터베이스 설정도 고려해야 합니다. 로컬 환경에서 사용한 SQLite 외에도 MySQL, PostgreSQL, Oracle 등 다양한 데이터베이스를 사용할 수 있습니다.

데이터베이스 설정은 Django 프로젝트의 `settings.py` 파일에서 관리합니다. 데이터베이스 엔진, 호스트, 포트, 사용자 이름, 비밀번호 등을 설정 파일에서 지정하여 데이터베이스에 연결합니다.


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

위의 예시는 MySQL 데이터베이스를 사용하는 설정입니다. 데이터베이스에 맞게 설정을 변경한 후 Django 프로젝트를 배포할 수 있습니다.


Leave a Comment