Django - Vue(Django 뼈대 만들기 , 2)
Project/Django & Vue.js

Django - Vue(Django 뼈대 만들기 , 2)

뉴비뉴 2019. 9. 2.

뼈대 만들기는 너무 간단하기 때문에 정리하지 않고 넘어가겠습니다.

프로젝트 디렉터리 mysite와 todo App을 생성해주면 됩니다.

 

코딩 순서는 

settings.py -> models.py -> urls.py -> views.py -> templates

 

1. settings.py

todo App을 INSTALLED_APP 에다가 추가 'todo',

template 디렉터리 지정 'DIRS': [os.path.join(BASE_DIR, 'templates')]

static 디렉터리 지정 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

 

2. models.py

테이블을 추가할 사항이 없으므로 pass

 

3. mysite/urls.py

path('todo/', include('todo.urls')),

urls.py 생성 시 항상 app_name !!

from django.urls import path
from . import views

app_name = 'todo'
urlpatterns = [
    path('vonly/', views.TodoVueOnlyTV.as_view(), name='vonly'),
]

4. views.py

from django.shortcuts import render
from django.views.generic import TemplateView


class TodoVueOnlyTV(TemplateView):
    template_name = 'todo/todo_vue_only.html'

5. templates

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue-Django ToDo App</title>

    <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: 70px;
            padding-left: 20px;
        }
        .inputBox .item {
            border-style: none;
            border-bottom: 1px solid #ddd;
            width: 400px;
            margin-left: 50px;
            padding-left: 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 {
            margin-left: auto;
            font-size: 20px;
        }
    </style>
</head>

<body>
    <div id='app'>

        <h1>My Todo App !</h1>
        <strong>서로 할 일이나 의견을 공유해 봅시다.</strong>
        <br>

        <div class="inputBox">
            <input class="name" type="text" placeholder="name ..." v-model="name"> <!--name변수를 v-model로 바인딩--><!-- newTodoItem을 바인딩 -->
            <input class="item" type="text" placeholder="type anything welcomed ..."
                   v-model="newTodoItem" v-on:keyup.enter="add_todo()">
            <button v-on:click="add_todo()">ADD</button>
        </div>
    
        <ul class="todoList">
            <li v-for="(todo, index) in todoItems">
                <span>{{ todo.name }}:: {{ todo.item }}</span> <!-- Django와 같이 data를 꺼내온다. -->
                <span class="removeBtn" v-on:click="remove_todo(index)">&#x00D7</span> <!-- remove_todo(index) 여기서 index는 글 번호를 말한다.-->
            </li>
        </ul>

    </div>

    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: '#app', // vue인스턴스를 적용할 element를 지정을하고, 56번 째 Line
            data: {
                name: '',
                newTodoItem: '',
                todoItems:[
                    {name: '김석훈', item: 'Django와 Vue.js 연동 프로그램을 만들고 있습니다.'}, // Python 의 객체와 같은 역할 70 Line
                    {name: '홍길동', item: '이름을 안쓰면 홍길동으로 나와요...'},
                    {name: '이순신', item: '신에게는 아직 열두 척의 배가 있사옵니다.'},
                    {name: '성춘향', item: '그네타기'},
                ],
            }, // DOM 엘리먼트에서 사용할 데이터를 지정을 한다. todoItems:[ ] 라는 어레이에 값을 넣는다.
            methods: {
                add_todo: function() {
                    console.log("add_todo()...");
                    if (this.name == '') this.name = '홍길동'; // name이 입력이 되어있지 않으면 '홍길동' 을 this.name으로 설정
                    if (this.newTodoItem == '') return; // newTodoItem이 입력되어있지 않으면 return
                    this.todoItems.push({name: this.name, item: this.newTodoItem}); // 데이터 옵션에서 정의한 변수들인데
                    // 이 변수들에는 현재 값이 없다, 사용자가 입력한 데이터를 넣기 위해서는 input 태그와 데이터바인딩을 해줘야한다.
                    this.name = ''; // push(ADD) 를 누른 이후에 입력창 clear
                    this.newTodoItem = '';  // push(ADD) 를 누른 이후에 입력창 clear
                },
                remove_todo: function(index) { // index를 인자를 넣어준다.
                    console.log("remove_todo()...");
                    this.todoItems.splice(index,1); // splice 함수 사용 index에서 한 개
                },
            },
        })
    </script>

</body>
</html>

하지만 여기서 문제가 발생한다, 바로 {{ todo.name }} :: {{ todo.item }} 부분이다.

왜냐하면 Django 와 문법이 겹치기 때문이다.

이럴 때는 Vue 옵션에서 Delimiters를 사용하면 된다.

delimiters: ['{', '}'],

 

1. todo-html

- html 파일에 vue.js 코드를 작성하는 방식

- 프로그램 종료 시, todo 데이터가 사라지는 단점

- 브라우저 Storage를 사용하면 todo 데이터가 유지되지만, 다른 환경에서는 볼 수 없음

 

2. todo-vue-only

- Django는 사용하지만 HTML 파일을 그대로 가져와서 사용하는 방식

- Django에서 제공하는 기능은 거의 사용하지 않는다.

- 테이블을 사용하지 않는다, todo 데이터 관련 단점은 1번과 동일

 

3. todo-django-only

- Vue.js 코드 없이, Django 코드 만으로 todo 앱을 개발하는 방식

- 테이블을 사용하므로, 다른 사람과 데이터 공유가 가능하다, 간단하고 쉬운 클래스형 뷰를 사용한다.

클래스형 뷰를 사용해보자.

- ListView : DB에서 레코드 목록을 가져와 보여주는 뷰

- CreateView : 폼에 입력한 내용으로, DB에 레코드를 생성하는 뷰

- UpdateView : DB에 있는 특정 레코드를 수정하는 뷰

- DeleteView : DB에 있는 특정 레코드를 삭제하는 뷰

 

 

댓글

💲 추천 글