컴퓨터와 책과 연필
블로그 프사

컴퓨터와 책과 연필

Kim Evergood

허접 개발자의 개인 블로그😘 문서화된 작업은 나의 얼굴. 문서화된 공부는 맞춤 교재.

장고 Django 시작하기

2025. 9. 12. Kim Evergood이가 씀.

일러두기

※ 여기서 /dir1/dir2처럼 /로 시작하는 경로 표시는 컴퓨터의 절대경로가 아니라 프로젝트 루트에서 시작하는 디렉토리를 나타낸다. 즉 앞의 예시는 { 프로젝트 루트 디렉토리 }/dir1/dir2이다.

장고 외 설정

아나콘다

아나콘다 설치 설명 건너뜀.

conda create -n web_env python=버전
condat activate web_env

MySQL 사용자

이 예에서는 MySQL을 사용한다.

sudo apt install mysql-server

sudo systemctl status mysql

# 보안 설정
sudo mysql_secure_installation

# MySQL에 관리자 권한으로 접속
sudo mysql

스키마 만들기

CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE test_db;

사용자 만들기

-- 사용자 생성
CREATE USER 'user1'@'%' IDENTIFIED BY 'password123';

-- 권한 부여
CREATE DATABASE test_db;
GRANT ALL PRIVILEGES ON test_db.* to 'user1'@'%';
FLUSH PRIVILEGES;

장고 소개

파이썬의 대표적인 웹 프레임워크

  • 한 프로젝트 안에 여러 앱을 포함하는 구조.
  • MVC 패턴 기반의 MVT 패턴을 이용한다.(Model, View, Template)
  • 자체 ORM
  • 자체 템플릿 엔진
  • 자동 구성되는 관리자 화면

장고 프로젝트 시작

장고 설치

# 아나콘다 이용시
conda install django

# 고전적인 파이썬 패키지 설치
pip install Django

프로젝트 생성

django-admin startproject { 프로젝트 이름 }
# 프로젝트 이름으로 폴더가 생긴다.
# 이후 작업은 프로젝트 루트 경로에서 진행하도록 그곳으로 이동한다.
cd { 프로젝트 이름 }

실행

python manage.py runserver

기본 포트번호는 8000이다. 로컬 실행 후 내 서버으로 접속하여 확인.

settings.py

참고: 장고 Documentatin - Settings Reference

DEBUG = True
# 개발중일 땐 True
ALLOWED_HOSTS = []
# 만약 운영중이면 서버가 실행하는 컴퓨터의 IP주소를 넣어야 한다.
# DEBUG = True이고 비어있으면 자동으로 localhost.
# 프로젝트에 포함되는 앱들을 모두 등록
INSTALLED_APPS = [
    'django.contrib.admin',
    # ...

    # 내가 생성한 앱
    'myapp2.apps.Myapp2Config', # python manage.py startapp myapp2 로 앱을 생성한 뒤

    # 서드파티 앱
    'crispy_forms',     # pip install crispy-bootstrap5
    'crispy_bootstrap5'
]
TEMPLATES = [
    {
        # ...
        'DIRS': [BASE_DIR / 'templates'], # 템플릿 소스 파일의 경로. 이리 설정하면 '/templates' 디렉토리에서 찾는다.
        # ...
    },
]
# DB 연결 설정
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # MySQL 사용
        'HOST': '127.0.0.1',    # DB 서버 주소
        'PORT': '3306',         # DB 서버 포트
        'NAME': 'test_db',      # 스키마
        'USER': 'user1',        # 사용자 계정
        'PASSWORD': 'password', # 사용자 계정 비밀번호
    }
}
LANGUAGE_CODE = 'ko-kr'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_TZ = True

앱 생성

# 프로젝트 루트 디렉토리
python manage.py startapp { 앱 이름 }
# 예: myapp1
python manage.py startapp myapp1

생성한 앱을 등록해야 한다.

# settings.py
INSTALLED_APPS = [
    # ...
    'myapp1.apps.Myapp1Config',
    # ...
]

MVT 맛보기

V: View

MVC의 Controller에 해당한다.

조금만 자세히

urls.py

자동생성된 /proj1/urls.py의 초기 내용은 이렇다.

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

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

view 호출

사용자가 특정 경로로 접근하면 어떻게 처리할지 정한다.

# /proj1/urls.py
from myapp1 import views

urlpatterns = [
    # ...
    path('say_hello/', views.welcome),
]

내 서버/say_hello/로 접속하면 /myapp1/views.py 파일의 welcome 함수가 호출되어 이 요청을 처리한다.

views.py 파일에 요청을 처리할 함수를 정의한다. 첫 번째 파라미터는 request이다.

# /myapp1/views.py
from django.shortcuts import render

def welcome(request):# 파라미터 request
    # 여기서 로직 처리
    return render(request, 'welcome.html')# 지정된 템플릿 파일을 렌더링하여 응답

render 함수를 호출하여 /myapp1/templates/welcome.html 파일을 렌더링 후 응답한다.

HTML 파일은 일반적인 HTML 형식도 가능하고; 그에 더해 템플릿 문법을 사용하는데 〈T: Template〉 장에서 더 자세히 설명한다.

M: Model

사용할 데이터의 정의.

조금만 자세히

모델 정의

# /myapp2/models.py
from django.db import models

class Board(models.Model):# models.Model를 상속하여 엔터티 정의
    # 각 필드를 정의
    # 명시적으로 PK 지정 안 하면 id 컬럼 자동 생성됨.
    b_title = models.CharField('제목', max_length=100)
    b_author = models.CharField('작성자', max_length=30)
    b_content = models.TextField('내용')
    b_like_count = models.PositiveIntegerField('좋아요', default=0)
    created_at = models.DateTimeField('작성시각', auto_now_add=True)
    updated_at = models.DateTimeField('수정시각', auto_now=True)

    class Meta:# 이 클래스의 부가정보
        ordering = ['-id']# 기본 정렬: id 내림차순

    def __str__(self):
        return self.b_title

class Comment(models.Model):
    c_author = models.CharField('작성자', max_length=30)
    c_content = models.CharField('내용', max_length=400)
    created_at = models.DateTimeField('작성시각', auto_now_add=True)
    board = models.ForeignKey(# 외래키
        Board,
        on_delete=models.CASCADE,
        related_name='comments')

    class Meta:
        ordering = ['-id']

    def __str__(self):
        return self.c_content

DB에 적용:

python manage.py makemigrations
python manage.py migrate

models.py에 작성한 대로 테이블이 생성된다.

View에서 사용

# /myapp2/views.py
from .models import Board

def b_list(request):

    posts = Board.objects.all()  # 모든 Board 개체 불러오기

    return render(request, 'bbs/list.html', {
        'posts': posts
    })
<!-- 템플릿에서 사용 예 -->
<tbody>
  {% for post in posts %}
  <tr>
    <td>{{ post.id }}</td>
    <td>{{ post.b_title }}</a></td>
    <td>{{ post.b_author }}</td>
  </tr>
  {% endfor %}
</tbody>

T: Template

MVC의 View에 해당한다.

조금만 자세히

JSP같네. 학원에서 잠깐 구경만 하고 넘어갔었지만 참 안구테러같다고 생각했지. 그런데 여기 똑같은 게 있어.

템플릿은 텍스트 파일이다. .html, .xml, .csv 등. 템플릿 문법으로 텍스트파일을 동적으로 생성한다.

기본적인 사용

view에서 render 호출시 context 인자로 동적인 값들을 넣어준다.

# views.py
def my_view1(request):

    return render(request, 'mytemplate1.html', {
        'val1': '값이다'
    })

변수: 받은 값을 {{, }} 사이에 쓸 수 있다.

<!-- mytemplate1.html -->
<p>{{ val1 }}</p>

태그: {%, %} 사이에 쓴다. 반복이나 논리 등을 나타낸다.

<tbody>
  {% for post in posts %}
  <tr>
    <td>{{ post.id }}</td>
    <td>{{ post.title }}</a></td>
    <td>{{ post.author }}</td>
  </tr>
  {% endfor %}
</tbody>

장고 관리자

urls.py에도 나와있듯; /admin으로 접속하면 된다.

관리자 계정 생성
python manage.py createsuperuser
# 이후 이름, 이메일, 비밀번호 입력
모델 등록
# /myapp2/admin.py
from django.contrib import admin

from .models import Board, Comment

admin.site.register(Board)
admin.site.register(Comment)

여기서 등록한 모델이 관리자 페이지에서 보인다.

그외

TODO name, namespace ???

참고

  • (학원 수업 내용)
728x90