728x90
Todo List 웹서비스 만들기
1. Todo List 웹서비스 시작하기
1.1 프로젝트 기능 정리
- Todo List 전체 조회하기
- Todo List 상세 조회하기
- Todo 생성하기
- 데이터 입력을 위한 Form 필요
- Todo 수정하기
- 데이터 수정을 위한 Form 필요
- Todo 생성용 Form 활용 가능
- Todo 완료 처리하기
1.2 프로젝트 생성
- 가상환경 설정
- powershell 이용
python -m venv django_todolist
cd django_todolist
./Scripts/activate
pip install django
python -m django --version
python --version
- Project 시작
django-admin startproject todoweb .
- 앱 추가
python manage.py startapp todolist
- 웹서버 실행
python manage.py runserver
1.3 프로젝트 설정
- 웹서버 설정 수정
# ./photoweb/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todolist', # 추가
]
TIME_ZONE = 'Asia/Seoul' # 타임존 변경
- Migration 수행
python manage.py migrate
- 계정 만들기
python manage.py createsuperuser
1.4 Todo 모델 생성
- Model 만들기
# ./todolist/models.py
from django.db import models
# Create your models here.
class Todo(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True)
created = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
important = models.BooleanField(default=False)
def __str__(self):
return self.title
- Model 적용시키기
python manage.py makemigrations
python manage.py migrate
Model을 Admin 페이지에 적용시키기
2. Todo 전체 조회 기능 만들기
2.1 Todo 전체 조회 기능 컨셉
- 첫 페이지에서 Todo List를 보여줌
- 완료되지 않은 항목만 보여줌
2.2 Bootstrap으로 좀 더 멋진 템플릿 만들기
- Bootstrap
- 웹 개발을 쉽게 할 수 있도록 도와주는 HTML, CSS, JavaScript 프레임워크
- Twitter의 개발자들이 처음 만들었으며, 현재는 오픈 소스로 제공 중
- 특징
- 반응형 디자인: 다양한 기기(모바일, 태블릿, 데스크탑)에서 잘 작동하도록 설계됨
- 미리 정의된 스타일: 버튼, 폼, 네비게이션 바 등 다양한 UI 요소에 대한 스타일 제공
- 확장성: 필요에 따라 커스터마이징이 가능하며, 다양한 플러그인과 함께 사용할 수 있음
- CDN 지원: 별도의 설치 없이 CDN 링크를 통해 쉽게 사용할 수 있음
2.3 Todo 전체 조회 뷰 만들기
# ./todolist/views.py
from django.shortcuts import render, redirect
from todolist.models import Todo
def todo_list(request):
todos = Todo.objects.filter(complete=False)
return render(request, 'todo_list.html', {'todos': todos})
2.4 Todo 전체 조회 템플릿 만들기
todolist 내 templates 폴더 만들기
# ./todolist/templates/todo_list.html
<html>
<head>
<title>TODO LIST APP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css" />
</head>
<body>
<div class="container">
<h1>TODO LIST APP</h1>
<p>
<a href=""><i class="bi-plus"></i>Add Todo</a>
<a href="" class="btn btn-primary" style="float:right">완료한 TODO 목록</a>
</p>
<ul class="list-group">
{% for todo in todos %}
<li class="list-group-item">
<a href="">{{ todo.title }}</a>
{% if todo.important %}
<span class="badge badge-danger">!</span>
{% endif %}
<div style="float:right">
<a href="" class="btn btn-danger">완료</a>
<a href="" class="btn btn-outline-primary">수정하기</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
2.6 Todo 전체 조회 URL 연결하기
# ./todolist/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.todo_list, name='todo_list'),
]
# ./todoweb/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path("", include('todolist.urls')),
]
http://127.0.0.1:8000/admin 에서 TODOLIST 제작
http://127.0.0.1:8000/admin 에서 TODOLIST 추가하기
http://127.0.0.1:8000 확인
3. Todo 상세 조회 기능 만들기
3.1 Todo 상세 조회 기능 컨셉
- Todo List에서 Todo를 선택했을 때 조회
- Todo의 제목과 설명을 보여줌
3.2 Todo 상세 조회 뷰 만들기
# ./todolist/views.py
from django.shortcuts import render, redirect
from .models import Todo
def todo_list(request):
todos = Todo.objects.filter(complete=False)
return render(request, 'todolist/todo_list.html', {'todos': todos})
def todo_detail(request, pk):
todo = Todo.objects.get(id=pk)
return render(request, 'todolist/todo_detail.html', {'todo': todo})
3.3 Todo 상세 조회 템플릿 만들기
# ./todolist/templates/todo_detail.html
<html>
<head>
<title>TODO LIST APP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css" />
</head>
<body>
<div class="container">
<h1>TODO 상세보기</h1>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ todo.title }}</h5>
<p class="card-text">{{ todo.description }}</p>
<a href="{% url 'todo_list' %}" class="btn btn-primary">목록으로</a>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
3.4 Todo 상세 조회 URL 연결하기
# ./todolist/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name='todo_list'),
path('<int:pk>/', views.todo_detail, name='todo_detail'),
]
3.5 Todo 전체 조회 템플릿 수정하기
- 상세 조회 페이지로 들어오기 위한 링크 걸기
# ./todolist/templates/todo_list.html
<html>
<head>
<title>TODO 목록 앱</title>
<link
rel="stylesheet"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<h1>TODO 목록 앱</h1>
<p>
<a href=""><i class="bi-plus"></i>Add Todo</a>
<a href="" class="btn btn-primary" style="float:right">완료한 TODO 목록</a>
</p>
<ul class="list-group">
{% for todo in todos %}
<li class="list-group-item">
<a href="{% url 'todo_detail' pk=todo.id %}">{{ todo.title }}</a>
{% if todo.important %}
<span class="badge badge-danger">!</span>
{% endif %}
<div style="float:right">
<a href="" class="btn btn-danger">완료</a>
<a href="" class="btn btn-outline-primary">수정하기</a>
</div>
</li>
{% endfor %}
</ul>
</body>
</div>
</html>
4. Todo 생성 기능 만들기
4.1 Todo 생성 기능 컨셉
- 제목, 설명, 중요도 입력
- Form 필요 → ./todolist/forms.py
4.2.1 Todo 내용 입력을 위한 Form 만들기
# ./todolist/forms.py
from django import forms
from .models import Todo
class TodoForm(forms.ModelForm):
class Meta:
model = Todo
fields = ('title', 'description', 'important')
4.3 Todo 생성 뷰 만들기
# ./todolist/views.py
from django.shortcuts import render, redirect
from .models import Todo
from .forms import TodoForm
def todo_list(request):
todos = Todo.objects.filter(complete=False)
return render(request, 'todolist/todo_list.html', {'todos': todos})
def todo_detail(request, pk):
todo = Todo.objects.get(id=pk)
return render(request, 'todolist/todo_detail.html', {'todo': todo})
def todo_post(request):
if request.method == "POST":
form = TodoForm(request.POST)
if form.is_valid():
todo = form.save(commit=False)
todo.save()
return redirect('todo_list')
else:
form = TodoForm()
return render(request, 'todolist/todo_post.html', {'form': form})
4.4 Todo 생성 템플릿 만들기
# ./todolist/templates/todo_post.html
<html>
<head>
<title>TODO LIST APP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css" />
</head>
<body>
<div class="container">
<h1>TODO 추가하기</h1>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<form method="POST">
{% csrf_token %} {{ form.as_p }}
<button type="submit" class="btn btn-primary">등록</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
4.5 Todo 전체 조회 템플릿 수정하기
- Todo 생성을 위한 링크 걸기
# ./todolist/templates/todo_list.html
<html>
<head>
<title>TODO 목록 앱</title>
<link
rel="stylesheet"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<h1>TODO 목록 앱</h1>
<p>
<a href="{% url 'todo_post' %}"><i class="bi-plus"></i>Add Todo</a> # 이부분
<a href="" class="btn btn-primary" style="float:right">완료한 TODO 목록</a>
</p>
<ul class="list-group">
{% for todo in todos %}
<li class="list-group-item">
<a href="{% url 'todo_detail' pk=todo.pk %}">{{ todo.title }}</a>
{% if todo.important %}
<span class="badge badge-danger">!</span>
{% endif %}
<div style="float:right">
<a href="" class="btn btn-danger">완료</a>
<a href="" class="btn btn-outline-primary">수정하기</a>
</div>
</li>
{% endfor %}
</ul>
</body>
</div>
</html>
4.6 Todo 생성 URL 연결하기
# ./todolist/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name='todo_list'),
path('<int:pk>/', views.todo_detail, name='todo_detail'),
path('post/', views.todo_post, name='todo_post'),
]
5. Todo 수정 기능 만들기
5.1 Todo 수정 기능 컨셉
- Todo 생성 기능과 거의 동일
- 선택된 Todo의 내용이 Form에 미리 입력되어 있음
5.2 Todo 수정 뷰 만들기
# ./todolist/views.py에 추가
def todo_edit(request, pk):
todo = Todo.objects.get(id=pk)
if request.method == "POST":
form = TodoForm(request.POST, instance=todo)
if form.is_valid():
todo = form.save(commit=False)
todo.save()
return redirect('todo_list')
else:
form = TodoForm(instance=todo)
return render(request, 'todo_post.html', {'form': form})
5.4 Todo 전체 조회 템플릿 수정하기
Todo 수정을 위한 링크 걸기
# ./todolist/templates/todo_list.html
<html>
<head>
<title>TODO 목록 앱</title>
<link
rel="stylesheet"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<h1>TODO 목록 앱</h1>
<p>
<a href="{% url 'todo_post' %}"><i class="bi-plus"></i>Add Todo</a>
<a href="" class="btn btn-primary" style="float:right">완료한 TODO 목록</a>
</p>
<ul class="list-group">
{% for todo in todos %}
<li class="list-group-item">
<a href="{% url 'todo_detail' pk=todo.pk %}">{{ todo.title }}</a>
{% if todo.important %}
<span class="badge badge-danger">!</span>
{% endif %}
<div style="float:right">
<a href="" class="btn btn-danger">완료</a>
<a href="{% url 'todo_edit' pk=todo.pk %}" class="btn btn-outline-primary">수정하기</a>
</div>
</li>
{% endfor %}
</ul>
</body>
</div>
</html>
5.4 Todo 수정 URL 연결하기
# ./todolist/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name='todo_list'),
path('<int:pk>/', views.todo_detail, name='todo_detail'),
path('post/', views.todo_post, name='todo_post'),
path('<int:pk>/edit/', views.todo_edit, name='todo_edit'),
]
6. Todo 완료 기능 만들기
6.1 Todo 완료 기능 컨셉
- 완료 버튼을 눌렀을 때 Todo의 complete 값을 True로 설정
- 완료 Todo 조회 기능: 완료된 Todo List만 보여줌
6.5 Todo 완료 URL 연결하기
# ./todolist/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name='todo_list'),
path('<int:pk>/', views.todo_detail, name='todo_detail'),
path('post/', views.todo_post, name='todo_post'),
path('<int:pk>/edit/', views.todo_edit, name='todo_edit'),
path('done/', views.done_list, name='done_list'),
path('done/<int:pk>/', views.todo_done, name='todo_done'),
]
6.4 Todo 완료 뷰 만들기
# ./todolist/views.py
from django.shortcuts import render, redirect
from .models import Todo
from .forms import TodoForm
def todo_list(request):
todos = Todo.objects.filter(complete=False)
return render(request, 'todolist/todo_list.html', {'todos': todos})
def todo_detail(request, pk):
todo = Todo.objects.get(id=pk)
return render(request, 'todolist/todo_detail.html', {'todo': todo})
def todo_post(request):
if request.method == "POST":
form = TodoForm(request.POST)
if form.is_valid():
todo = form.save(commit=False)
todo.save()
return redirect('todo_list')
else:
form = TodoForm()
return render(request, 'todolist/todo_post.html', {'form': form})
def todo_edit(request, pk):
todo = Todo.objects.get(id=pk)
if request.method == "POST":
form = TodoForm(request.POST, instance=todo)
if form.is_valid():
todo = form.save(commit=False)
todo.save()
return redirect('todo_list')
else:
form = TodoForm(instance=todo)
return render(request, 'todolist/todo_post.html', {'form': form})
def done_list(request):
dones = Todo.objects.filter(complete=True)
return render(request, 'todo/done_list.html', {'dones': dones})
def todo_done(request, pk):
todo = Todo.objects.get(id=pk)
todo.complete = True
todo.save()
return redirect('todo_list')
6.2 Todo 완료 템플릿 만들기
# ./todolist/templates/done_list.html
<html>
<head>
<title>TODO LIST APP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css" />
</head>
<body>
<div class="container">
<h1>완료된 TODO 목록</h1>
<p> <a href="{% url 'todo_list' %}" class="btn btn-primary">홈으로</a> </p>
<ul class="list-group">
{% for done in dones %}
<li class="list-group-item">
<a href="{% url 'todo_detail' pk=done.id %}">{{ done.title }}</a>
{% if done.important %}
<span class="badge badge-danger">!</span>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
6.3 Todo 전체 조회 템플릿 수정하기
- Todo 완료를 위한 링크 걸기
# ./todolist/templates/todo_list.html
<html>
<head>
<title>TODO LIST APP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css" />
</head>
<body>
<div class="container">
<h1>TODO LIST APP</h1>
<p>
<a href="{% url 'todo_post' %}"><i class="bi-plus"></i> Add Todo</a>
<a href="{% url 'done_list' %}" class="btn btn-primary" style="float:right">완료한 TODO 목록</a>
</p>
<ul class="list-group">
{% for todo in todos %}
<li class="list-group-item">
<a href="{% url 'todo_detail' pk=todo.id %}">{{ todo.title }}</a>
{% if todo.important %}
<span class="badge badge-danger">!</span>
{% endif %}
<div style="float:right">
<a href="{% url 'todo_done' pk=todo.id %}" class="btn btn-danger">완료</a>
<a href="{% url 'todo_edit' pk=todo.id %}" class="btn btn-outline-primary">수정하기</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
완료 버튼을 누르게 되면 완료된 TODO 목록으로 들어간다.
728x90
'PYTHON-BACK' 카테고리의 다른 글
#파이썬 27일차_MYSQL3 (0) | 2024.08.07 |
---|---|
#파이썬 26일차_MYSQL2 (0) | 2024.08.06 |
#파이썬 23일차_Django_개발환경/동작원리/실습1 (0) | 2024.07.31 |
#파이썬 22일차_Django (0) | 2024.07.30 |
#파이썬 22일차_GitHub Action (0) | 2024.07.30 |