Search
Duplicate

Todo List

ν”„λ‘œμ νŠΈ ꡬ쑰

ν”„λ‘œμ νŠΈ 생성

django-admin startproject todolist cd todolist
Bash
볡사

μ•± 생성

python manage.py startapp todo
Bash
볡사

μ•± 등둝 (settings.py)

# Application definition ## todo μ•± 등둝 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todo' ]
Python
볡사

λͺ¨λΈ μ •μ˜ (models.py)

from django.db import models # Create your models here. class Todo(models.Model): STATUS_CHOICE = [ ('WAIT', 'λŒ€κΈ°'), ('ING', 'μ§„ν–‰'), ('DONE', 'μ™„λ£Œ') ] no = models.AutoField(primary_key=True) # μžλ™ 증가 ν•„λ“œ(PK) title = models.CharField(max_length=255) status = models.CharField( max_length=20, choices=STATUS_CHOICE, default='WAIT' ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return "{} : {}".format(self.title, self.status)
Python
볡사

λ§ˆμ΄κ·Έλ ˆμ΄μ…˜

# λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 파일 생성 python manage.py makemigrations # λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ‹€ν–‰ python manage.py migrate
Bash
볡사

URL λ§€ν•‘ (urls.py)

from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('todo', views.todo, name='todo'), path('create', views.create, name='create'), path('delete', views.delete, name='delete'), path('ing', views.ing, name='ing'), path('done', views.done, name='done'), path('wait', views.wait, name='wait'), ]
Python
볡사

View μ •μ˜ (views.py)

from django.shortcuts import render from django.http import HttpResponseRedirect from django.urls import reverse from django.db.models import Q from .models import * # models 의 λͺ¨λ“  λͺ¨λΈ import # Create your views here. def index(request): print('메인 ν™”λ©΄...') return render(request, 'todo/index.html', {}) def todo(request): print('ν•  일 λͺ©λ‘ ν™”λ©΄...') # ν•  일 λͺ©λ‘ 쑰회 # Todo λͺ¨λΈμ˜ λŒ€κΈ° λͺ©λ‘ 쑰회 wait_list = Todo.objects.filter(status='WAIT') # Todo λͺ¨λΈμ˜ μ§„ν–‰ λͺ©λ‘ 쑰회 ing_list = Todo.objects.filter(Q(status='ING') | Q(status='DONE')).order_by('-status') content = {'wait_list': wait_list, 'ing_list': ing_list} # render(request, ν…œν”Œλ¦Ώ 경둜, 데이터{}) # - 데이터{} : ν…œν”Œλ¦Ώμ— 데이터λ₯Ό 전달 return render(request, 'todo/todo.html', content) def create(request): print('ν•  일 등둝...') # POST λ°©μ‹μ˜ νŒŒλΌλ―Έν„° title = request.POST['title'] # 등둝 μš”μ²­ new_todo = Todo(title = title) new_todo.save() # DB에 μ €μž₯ # ν•  일 λͺ©λ‘(todo)으둜 λ¦¬λ‹€μ΄λ ‰νŠΈ return HttpResponseRedirect(reverse('todo')) def delete(request): print("μ‚­μ œ μš”μ²­...") # νŒŒλΌλ―Έν„° no = request.POST['no'] print('no : {}'.format(no)) try: todo = Todo.objects.get(no=no) todo.delete() # ν•  일 μ‚­μ œ μš”μ²­ except Todo.DoesNotExist: print('μ‚­μ œν•  ν•  일이 μ—†μŠ΅λ‹ˆλ‹€.') return HttpResponseRedirect(reverse('todo')) def ing(request): print('μ§„ν–‰ μƒνƒœλ‘œ λ³€κ²½...') no = request.POST['no'] print('no : {}'.format(no)) try: todo = Todo.objects.get(no=no) # ν•  일 μƒνƒœ μˆ˜μ • todo.status = 'ING' todo.save() except Todo.DoesNotExist: print('μˆ˜μ •ν•  ν•  일이 μ—†μŠ΅λ‹ˆλ‹€.') return HttpResponseRedirect(reverse('todo')) def done(request): print('μ™„λ£Œ μƒνƒœλ‘œ λ³€κ²½...') no = request.POST['no'] print('no : {}'.format(no)) try: todo = Todo.objects.get(no=no) # ν•  일 μƒνƒœ μˆ˜μ • if todo.status == 'DONE': todo.status = 'ING' else: todo.status = 'DONE' todo.save() except Todo.DoesNotExist: print('μˆ˜μ •ν•  ν•  일이 μ—†μŠ΅λ‹ˆλ‹€.') return HttpResponseRedirect(reverse('todo')) def wait(request): print('λŒ€κΈ° μƒνƒœλ‘œ λ³€κ²½...') no = request.POST['no'] print('no : {}'.format(no)) try: todo = Todo.objects.get(no=no) # ν•  일 μƒνƒœ μˆ˜μ • todo.status = 'WAIT' todo.save() except Todo.DoesNotExist: print('μˆ˜μ •ν•  ν•  일이 μ—†μŠ΅λ‹ˆλ‹€.') return HttpResponseRedirect(reverse('todo'))
Python
볡사

Template μž‘μ„±

└── templates/ β”œβ”€β”€ todo/ β”‚ β”œβ”€β”€ index.html β”‚ └── todo.html
Plain Text
볡사

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>메인 ν™”λ©΄</title> </head> <body> <h1>메인 ν™”λ©΄</h1> <h3>Hello Django~!</h3> <a href="./todo">To Do List</a> </body> </html>
HTML
볡사

todo.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ν•  일 λͺ©λ‘</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css"> <style> input[type='checkbox'] { cursor: pointer; } </style> </head> <body> <div class="container"> <div class="row justify-content-center"> <div class="col-12 col-md-8 col-lg-6"> <h1>ν•  일 λͺ©λ‘</h1> <hr> <form action="./create" method="post"> {% csrf_token %} <div class="input-group mb-3"> <label for="todo" class="input-group-text">ν•  일</label> <input type="text" name="title" class="form-control" id="todo" placeholder="ν•  일을 μž…λ ₯ν•΄μ£Όμ„Έμš”." autofocus > <button type="submit" class="btn btn-outline-primary">등둝</button> </div> </form> <hr> <h3>μ§„ν–‰ λͺ©λ‘</h3> <table class="table table-bordered text-center align-middle"> <thead> <tr class="table-dark"> <th>βœ…</th> <th class="text-start">ν•  일</th> <th>⭐</th> </tr> </thead> <tbody> {% for todo in ing_list %} <tr {% if todo.status == 'DONE' %}class="table-success"{% endif %}> <td> <form action="./done" method="post"> {% csrf_token %} <input type="hidden" name="no" value="{{ todo.no }}"> <input type="checkbox" class="form-check-input" onchange="this.form.submit()" {% if todo.status == 'DONE' %}checked{% endif %}> </form> </td> <td class="text-start"> {{ todo.title }} </td> <td> <div class="d-flex justify-content-center gap-2"> <form action="./wait" method="post"> {% csrf_token %} <input type="hidden" name="no" value="{{ todo.no }}"> <button class="btn btn-success"> <i class="bi bi-arrow-down-square"></i> </button> </form> <form action="./delete" method="post"> {% csrf_token %} <input type="hidden" name="no" value="{{ todo.no }}"> <button class="btn btn-danger"> <i class="bi bi-trash2"></i> </button> </form> </div> </td> </tr> {% empty %} <tr> <td colspan="3" class="text-center text-muted"> 쑰회된 데이터가 μ—†μŠ΅λ‹ˆλ‹€. </td> </tr> {% endfor %} </tbody> </table> <hr> <h3>λŒ€κΈ° λͺ©λ‘</h3> <table class="table table-bordered text-center align-middle"> <thead> <tr class="table-dark"> <th>βœ…</th> <th class="text-start">ν•  일</th> <th>⭐</th> </tr> </thead> <tbody> {% for todo in wait_list %} <tr> <td> <form action="./ing" method="post"> {% csrf_token %} <input type="hidden" name="no" value="{{ todo.no }}"> <button type="submit" class="btn btn-outline-primary"> <i class="bi bi-arrow-up-square"></i> </button> </form> </td> <td class="text-start"> {{ todo.title }} </td> <td> <form action="./delete" method="post"> {% csrf_token %} <input type="hidden" name="no" value="{{ todo.no }}"> <button class="btn btn-danger"> <i class="bi bi-trash2"></i> </button> </form> </td> </tr> {% empty %} <tr> <td colspan="3" class="text-center text-muted"> 쑰회된 데이터가 μ—†μŠ΅λ‹ˆλ‹€. </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js" integrity="sha384-j1CDi7MgGQ12Z7Qab0qlWQ/Qqz24Gc6BM0thvEMVjHnfYGF0rmFCozFSxQBxwHKO" crossorigin="anonymous"></script> </body> </html>
HTML
볡사