Create / Read / Update / Delete
대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능
STEP 1 python version / virtual environment check
$ python --version
$ pip install django
$ django-admin startproject mytodo .
STEP 4 todo App 생성
$ python manage.py startapp todo
STEP 5 app add > settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo', # todo 추가해준 것
]
STEP 6 시간대 변경
TIME_ZONE = 'Asia/Seoul'
STEP 8 forms.py , models.py , urls.py 생성 > todo folder
$ python manage.py createsuperuser
STEP 1 model 생성
# todo/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
프로젝트 생성 후 최초의 마이그레이션이므로 기본 모델까지 마이그레이션 될 수 있도록 앱 지정 X
$ python manage.py makemigrations
$ python manage.py migrate
# todo/admin.py
from django.contrib import admin
from .models import Todo
# Register your models here.
admin.site.register(Todo)
urlpatterns = [
path('admin/', admin.site.urls),
]
STEP 1 templates 생성
Todo 목록 조회 기능 templates 생성
> 완료되지 않은 Todo만 보여주도록 구현
# todo/templates/todo/todo_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo List</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous"> # Bootstrap homepage 공식 문서 참조
</head>
<body>
<div class = "container">
<h1>Todo List</h1>
<p>
<a href=""><i class = "bi-plus">Add Todo</i></a>
<a href="" class="btn btn-primary" style ="float:right">완료한 Todo List </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-primary">완료</a>
<a href="" class ="badge badge-danger">Edit Todo</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
# todo/views.py
from django.shortcuts import render
from .models import Todo
# 목록 화면 뷰
def todo_list(request): # 완료되지 않은 Todo 만 전달해야하므로 complete = False filtering
todos = Todo.objects.filter(complete=False)
return render(request, 'todo/todo_list.html',{'todos':todos})
# todo/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.todo_list, name='todo_list'),
] # 주소에 todo_list view 연결
# mytodo/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('todo.urls')),
]
STEP 1 templates 생성
> Todo 를 선택했을 때 조회할 수 있는 기능으로 Todo 제목과 설명 구현
> Bootstrap 을 활용해서 스타일 적용
> Todo 제목과 설명을 보여주도록 구현
> 목록으로 다시 돌아갈 수 있는 버튼 구현
# todo/templates/todo/todo_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo List</title>
</head>
<body>
<div class ="container">
<h1>Todo Detail</h1>
<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>
</body>
</html>
# 상세 조회 뷰
def todo_detail (request,pk):
todo = Todo.objects.get(id=pk)
# todo 변수에 Todo model로 들어오는 데이터를 id로 구분해서 하나씩 가져와 저장
return render (request, 'todo/todo_detail.html', {'todo':todo})
path('<int:pk>/',views.todo_detail, name ='todo_detail'),
# url > /pk/ 설정하여 해당하는 pk의 Todo 연결, pk : 몇 번째 todo인지 구분하기 위함
todo 의 title click > views.py 에 의해 todo_detail 함수 호출
<a href="{% url 'todo_detail' pk=todo.pk %}"> {{todo.title}}</a>
STEP 1 form 생성
# todo/forms.py
# 제목, 설명, 중요도 입력하기 위한 것
from django import forms
from .models import Todo
class TodoForm(forms.ModelForm):
class Meta:
model = Todo
fields = ('title','description','important')
# todo/templates/todo/todo_post.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo Post</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
</head>
<body>
<div class = 'container'>
<h1>Todo Add</h1>
<div class = 'container'>
<div class = 'row'>
<div class = 'row'>
<div class = 'col-md-12'>
<div class = 'card'>
<div class = 'card-body'>ig
<form method ='POST'>cd
{% csrf_token %} {{form.as_p}}
<button type ='submit' class = 'btn btn-primary'>Add</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
# todo/views.py
def todo_post(request):
if request.method == "POST": # POST 요청이 들어오는 경우
form = TodoForm(request.POST)
if form.is_valid():
todo = form.save(commit=False)
todo.save()
return redirect('todo_list')
else: # GET 요청이 들어오는 경우
form = TodoForm()
return render(request,'todo/todo_post.html',{'form':form})
path('post/',views.todo_post, name='todo_post'),
Add Todo click > view.py에 todo_post 함수 호출
<a href = "{% url 'todo_post' %}"><i class = "bi-plus"></i> Add Todo </a>
STEP 1 templates 생성
# todo/templates/todo/todo_edit
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo Edit</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
</head>
<body>
<div class = 'container'>
<h1>Todo Add</h1>
<div class = 'container'>
<div class = 'row'>
<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'>Update</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
# todo/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/todo_edit.html',{'form':form})
path('<int:pk>/edit/',views.todo_edit,name='todo_edit'),
<a href = "{% url 'todo_edit' pk = todo.pk %}" class = "btn btn-outline-primary"> Edit</a>
complete button click > Todo의 complete = True로 설정해 주는 기능
STEP 1 templetes 생성
# todo/templates/todo/done_list
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo List</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
</head>
<body>
<div class ='container'>
<h1>Done List</h1>
<p>
<a href="{% url 'todo_list' %}">홈으로</a>
</p>
<ul class="list-group">
{% for done in dones %}
<li class="list-group-item">
<a href="{% url 'todo_detail' pk=done.pk %} ">{{done.title}}</a>
{% if done.important %}
<span class="badge-danger">!</span>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
# todo/views.py
# 완료 목록 뷰
def done_list(request):
dones = Todo.objects.filter(complete=True)
return render(request, 'todo/done_list.html',{'dones':dones})
> dones 변수에 저장 : complete = True 로 필터링 된 데이터
# 완료로 바꾸는 뷰
def todo_done(request,pk):
todo = Todo.objects.get(id=pk)
todo.complete = True
todo.save()
return redirect('todo_list')
> Todo 객체를 id 로 구분 > todo 변수에 저장 > todo를 complet=True 로 설정 > todo.save()로 상태 저장
path('done/',views.done_list, name='done_list'),
path('done/<int:pk>/', views.todo_done,name = 'todo_done'),
<a href = "{% url 'done_list' %}" class = "btn btn-primary" style = "..."> 완료한 Todo List </a>
<a href = "{% url 'todo_done' pk = todo.pk %}" class = "btn btn-danger"> 완료 </a>
Todo 목록 서비스는 모든 프레임워크를 공부할 때 대표적 예제로 많이 사용되는 것을 기반으로 Todo project를 생성하고 이에 필요한 모델과 각 조회 기능을 만들어 적용시키는 실습 위주의 스터디 진행