models.py
코딩하기
from django.db import models
class Todo(models.Model):
name = models.CharField('NAME', max_length=5, blank=True)
todo = models.CharField('TODO', max_length=50)
def __str__(self):
return self.todo
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if not self.name:
self.name = '홍길동'
super().save()
어드민에서 보여질 컬럼들을 코딩한다.
admin.py
from django.contrib import admin
from todo.models import Todo
@admin.register(Todo)
class TodoAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'todo')
테이블을 데이터베이스에 반영하기 위해서 마이그레이션을 진행한다.
python manage.py makemigrations
python manage.py migrate
Todo 테이블 작업을 완료했으면 이제 순차적으로 코딩을 시작한다.
mysite/urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.HomeView.as_view(), name='home'),
path('todo/', include('todo.urls')),
]
todo/urls.py
from django.urls import path
from . import views
app_name = 'todo'
urlpatterns = [
path('', views.TodoTV.as_view(), name='index'),
]
todo/views.py
from django.views.generic import TemplateView
class TodoTV(TemplateView):
template_name = 'todo/todo_index.html'
todo 앱에 templates 경로를 만들고 todo 경로를 만든다.
todo_index.html
{% extends 'base.html' %}
{% block title %}Vue.js - Django todo app{% endblock %}
{% block extra-style %}
<style>
body {
text-align: center;
background-color: #ddd;
}
.inputBox {
margin: auto;
width: 70%;
background: white;
height: 50px;
border-radius: 50px;
line-height: 50px;
}
.inputBox .name {
border-style: none;
border-bottom: 1px solid #ddd;
width: 90px;
padding-left: 20px;
line-height: 20px;
}
.inputBox .item {
border-style: none;
border-bottom: 1px solid #ddd;
width: 400px;
margin-left: 50px;
padding-left: 20px;
line-height: 20px;
}
.todoList {
list-style: none;
padding: 10px 0;
text-align: left;
}
.todoList li {
display: flex;
height: 50px;
line-height: 50px;
margin: 0.5rem 0;
padding: 0 0.9rem;
background: white;
border-radius: 5px;
}
.removeBtn {
font-size: 20px;
cursor: pointer;
height: 30px;
line-height: 0;
margin: auto 0 auto auto;
}
.removeBtn:hover {
color: #de4d85;
}
</style>
{% endblock %}
{% block content %}
<div id='app'>
<h1>My Todo App !</h1>
<strong>서로 할 일이나 의견을 공유해 봅시다.</strong>
<br>
<div>
<input class="name" type="text" placeholder="name ..." v-model.trim="name">
<!-- v-model에 .trim 이라는 수식어를 사용하면 앞뒤 공백을 삭제해서 삽입한다. -->
<input class="item" type="text" placeholder="type anything welcomed ..." v-model.trim="todo" @keyup.enter="add_todo()">
<button class="btn btn-primary btn-sm" @click="add_todo()">ADD</button>
</div>
<ul class="todoList">
<li v-for="(todo, index) in todoList">
<span>{ todo.name } :: { todo.todo }</span>
<span class="removeBtn" @click="remove_todo(index)">×</span>
</li>
</ul>
</div>
{% endblock %}
{% block extra-script %}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
delimiters: ['{', '}'],
el: '#app',
data: {
name: '',
todo: '',
todoList: [
{name: '테스트1', todo: '테스트 내용 1'},
{name: '테스트4', todo: '테스트 내용 4'},
{name: '테스트2', todo: '테스트 내용 2'},
{name: '테스트3', todo: '테스트 내용 3'},
],
},
methods: {
add_todo: function () {
console.log("add_todo()...");
if (this.name === '') {
this.name = 'user'
}
if (this.todo === '') {
return;
}
this.todoList.push({name: this.name, todo: this.todo});
this.name = this.todo = '';
},
remove_todo: function (index) {
console.log(index);
this.todoList.splice(index, 1);
},
},
})
</script>
{% endblock %}
이 후 base.html
에 todo로 가는 링크를 수정한다.
<a class="nav-link text-white" href="{% url 'todo:index' %}">Todo</a></li>
GitHub Source
👉🏻깃허브 소스