더보기
74일 차 회고.
이번 주 주말은 약속이 없어서 집에서 쉬면서 AWS 공부나 자격증 공부를 시작해 볼 생각이다.
1. Django
1-1. MySQL
가상환경 생성
uv venv .venv -p 3.13
.\.venv\Scripts\activate
uv pip install -r .\requirements.txt
# requirements.txt
django
mysqlclient
Django 프로젝트 생성
django-admin startproject config .
Django 앱 생성
python manage.py startapp todolist
templates 생성
mkdir templates
mkdir .\templates\todolist
코드 작성
- TEMPLATE
<!--templates/todolist/todolist.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo List</title>
<script src="//d.bablic.com/snippet/6288d4c3c4c5800001a91242.js?version=3.9"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<h1 class="fs-1 fw-bold p-2">Todo List</h1>
<section class="vh-100" style="background-color: #eee;">
<div class="container text-center font-monospace py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col col-lg-9 col-xl-7">
<div class="card rounded-3">
<div class="card-body p-4">
{% if messages %}
{% for message in messages %}
<h4 class="text-center font-monospace" style="color: #b22222;">{{message}}</h4>
{% endfor %}
{% endif %}
<h4 class="text-center font-monospace my-3 pb-3">Todo List</h4>
<form method="POST" class="row row-cols-lg-auto g-3 justify-content-center align-items-center mb-4 pb-2">
{% csrf_token %}
<div class="col-12">
<div class="form-outline">
<input type="text" id="form1" class="form-control" name="task" placeholder="Enter a task here"/>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-outline-primary">Add Task</button>
</div>
</form>
<table class="table mb-4">
<thead>
<tr>
<th scope="col">Todo Item</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{% for i in todo_list %}
<tr>
<td>{{i.title}}</td>
{% if i.status == True %}
<td>Completed</td>
{% else %}
<td>In progress</td>
{% endif %}
<td>
<a href=""><button type="submit" class="btn btn-outline-success col-5">Finished</button></a>
<a href=""><button type="submit" class="btn btn-outline-danger col-5">Delete</button></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>
- VIEW (Todolist 조회 및 생성)
# todolist/views.py
from django.shortcuts import render
from django.contrib import messages
from .models import TodoList
def todolist(request):
if request.method == 'POST':
task = request.POST.get('task').strip()
if TodoList.objects.filter(title=task).exists():
messages.error(request=request, message='TASK already EXISTS!')
elif not len(task):
messages.error(request=request, message='TASK CANNOT be EMPTY!')
else:
new_task = TodoList(title=task)
new_task.save()
context = {
'todo_list': TodoList.objects.all(),
}
return render(request, 'todolist/todolist.html', context)
- MODEL
# todolist/models.py
from django.db import models
class TodoList(models.Model):
title = models.CharField(max_length=200)
status = models.BooleanField(default=False)
def __str__(self):
return self.title
- URL RESOLUTION
# todolist/urls.py
from django.urls import path
from .views import todolist
urlpatterns = [
path('', todolist, name='todolist'),
]
# config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('todolist.urls')),
]
- SETTING
# config/settings.py
import os
from pathlib import Path
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todolist',
]
...
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '',
'USER': '',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': '3306',
}
}
...
Docker Container 생성
# docker-compose.yml
version: "3"
services:
db-mysql:
image: mysql
restart: always
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
- ./database/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: r1234
MYSQL_DATABASE: django_db
MYSQL_USER: django_root
MYSQL_PASSWORD: r1234
ports:
- "3306:3306"
# POWERSHELL
cd <file_path>
docker compose up -d
서버 실행
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Database 확인

코드 작성
- TEMPLATE
<!--templates/todolist/todolist.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo List</title>
<script src="//d.bablic.com/snippet/6288d4c3c4c5800001a91242.js?version=3.9"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<h1 class="fs-1 fw-bold p-2 text-center" style="color:lightseagreen;">Todo List</h1>
<section class="vh-100" style="background-color: #eee;">
<div class="container text-center font-monospace py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col col-lg-9 col-xl-7">
<div class="card rounded-3">
<div class="card-body p-4">
{% if messages %}
{% for message in messages %}
<h4 style="color: #b22222;">{{message}}</h4>
{% endfor %}
{% endif %}
<h2 class="fw-bold my-3 pb-3">Todo List</h2>
<form method="POST" class="row row-cols-lg-auto g-3 justify-content-center align-items-center mb-4 pb-2">
{% csrf_token %}
<div class="col-12">
<div class="form-outline">
<input type="text" id="form1" class="form-control" name="task" placeholder="Enter a task here"/>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-outline-primary">Add Task</button>
</div>
</form>
<table class="table mb-4">
<thead>
<tr>
<th scope="col">Todo Item</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{% for i in todo_list %}
<tr>
<td>{{i.title}}</td>
{% if i.status == True %}
<td>Complete</td>
{% else %}
<td>In progress</td>
{% endif %}
<td>
<a href="{% url 'todolist-update' i.id %}"><button type="submit" class="btn btn-outline-success col-5">Finished</button></a>
<a href="{% url 'todolist-delete' i.id %}"><button type="submit" class="btn btn-outline-danger col-5">Delete</button></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>
- VIEW (Todolist 삭제 및 수정)
# todolist/views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import TodoList
def todolist(request):
if request.method == 'POST':
task = request.POST.get('task').strip()
if TodoList.objects.filter(title=task).exists():
messages.error(request=request, message='TASK ALREADY EXISTS!')
elif not len(task):
messages.error(request=request, message='TASK CANNOT BE EMPTY!')
else:
new_task = TodoList(title=task)
new_task.save()
context = {
'todo_list': TodoList.objects.all(),
}
return render(request, 'todolist/todolist.html', context)
def update_task(request, task_id):
task = TodoList.objects.get(id=task_id)
task.status = True
task.save()
return redirect(to='todolist')
def delete_task(request, task_id):
TodoList.objects.get(id=task_id).delete()
return redirect(to='todolist')
- URL RESOLUTION
# todolist/urls.py
from django.urls import path
from .views import todolist, delete_task, update_task
urlpatterns = [
path('', todolist, name='todolist'),
path('todolist-update/<int:task_id>', update_task, name='todolist-update'),
path('todolist-delete/<int:task_id>', delete_task, name='todolist-delete'),
]
서버 실행
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
코드 작성
- TEMPLATE
<!--templates/base/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
{% block stylesheet %}{% endblock %}
</head>
<body>
{% block content %}
{% endblock %}
{% block script %}{% endblock %}
</body>
</html>
<!--templates/todolist/todolist.html-->
{% extends 'base/index.html' %}
{% block title %}Todo List Page{% endblock %}
{% block stylesheet %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
{% endblock %}
{% block script %}
<script src="//d.bablic.com/snippet/6288d4c3c4c5800001a91242.js?version=3.9"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
{% endblock %}
{% block header %}Todo List{% endblock %}
{% block content %}
<section class="vh-100" style="background-color: #eee;">
<div class="container text-center font-monospace py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col col-lg-9 col-xl-7">
<div class="card rounded-3">
<div class="card-body p-4">
{% if messages %}
{% for message in messages %}
<h4 style="color: #b22222;">{{message}}</h4>
{% endfor %}
{% endif %}
<h2 class="fw-bold my-3 pb-3">Todo List</h2>
<form method="POST" class="row row-cols-lg-auto g-3 justify-content-center align-items-center mb-4 pb-2">
{% csrf_token %}
<div class="col-12">
<div class="form-outline">
<input type="text" id="form1" class="form-control" name="task" placeholder="Enter a task here"/>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-outline-primary">Add Task</button>
</div>
</form>
{% if todo_list|length > 0 %}
<table class="table mb-4">
<thead>
<tr>
<th scope="col">Todo Item</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{% for i in todo_list %}
<tr>
<td>{{i.title}}</td>
{% if i.status == True %}
<td>Complete</td>
{% else %}
<td>In progress</td>
{% endif %}
<td>
<a href="{% url 'todolist-update' i.id %}"><button type="submit" class="btn btn-outline-success col-5">Finished</button></a>
<a href="{% url 'todolist-delete' i.id %}"><button type="submit" class="btn btn-outline-danger col-5">Delete</button></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h4 style="color: lightseagreen;">No tasks available</h4>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
서버 실행
python manage.py makemigrations
python manage.py migrate
python manage.py runserver


'SK네트웍스 Family AI캠프 10기 > Daily 회고' 카테고리의 다른 글
| 76일차. Django (0) | 2025.04.29 |
|---|---|
| 75일차. Django (0) | 2025.04.28 |
| 73일차. Django (0) | 2025.04.24 |
| 72일차. JavaScript & Django (0) | 2025.04.23 |
| 71일차. JavaScript (0) | 2025.04.22 |