Django #7 - Todo 앱 설계 (Vue-Django 연동)

Corner·2022년 4월 24일
0

django

목록 보기
9/14
post-thumbnail

Vue-Django 연동 설계 - 1

Vue.js <------------> Django

  1. 첫 페이지는 Django에서 생성해서, 클라이언트에게 보내 줌
  2. 이후 화면 렌더링은, Vue.js 코드에서 수행
  3. Data 저장은 서버 측의 DB에 저장 (SQLite)
  4. Client-Server 간 Data 연동은 JSON 포맷으로
  5. Vue.js의 directive/axios 기능 사용
  6. DRF(Django Rest Framework) 대신에, JsonResponse 사용

Vue-Django 연동 설계 - 2

​ JSON 방식

Vue.js <-------------------------------------------> Django

Vue.js(axios) <---------------------JSON 방식---->Django(JsonResponse)
브라우저에서 첫 페이지 요청 ----> request
<-------------------------index.html(data, html/css/js)

Server Rendering
Django에서 첫화면용 HTML/CSS 생성
- 빈 화면일 수도 있다.
- Vue.js 코드 들어있다.

Server Rendering
(버튼 클릭 등)Vue.js의 axios 기능 ----------> 비동기 request
<--------------------- json 응답 (data)

Client Rendering
Django의 JsonResponse 기능

Client Rendering

vue.js에서는 Virtual DOM 방식으로 처리하기 때문에 화면 깜박임이 없어서 사용자 경험이 좋아지게 되는 효과가 있으며, Data만 있기 때문에 트래픽 감소로 응답속도가 빠르다.


🌱Vue-Django 연동하기 - 기본 코딩

todo 앱 골격 만들기

지금까지 여러가지 방식으로 Todo 앱을 개발했는데,

이번에는 todo-vue-django 방식으로

  • Vue.js -- Django 연동 방식 (JSON 포맷)
  • VueOnly 소스에, 데이터 처리를 위한 JSON 연동기능 추가
  • VueOnly + axios + JsonResponse

또한 메인메뉴도 대폭 수정하도록 할 것이다.

프로젝트 생성

기존에 만든 인터프리터를 체크하고 생성한다.

pip list 명령어로 확인해보면 이미 Django가 설치 돼있기 때문에 어드민 명령어로 뼈대를 구축할 수 있다.

$ django-admin startproject mysite .

mysite project 생성

$ python manage.py migrate

db 생성

$ python manage.py createsuperuser
$ name
$ email 생략 가능
$ password

admin 슈퍼계정 생성

$ python manage.py startapp todo

root/mysite/settings.py

APPS에 추가하고, TimeZone 변경, USE_TZ 변경, STATICFILES_DIRS 추가

"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 3.2.13.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os.path
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-k=o%1y&8wmtq6tfshbpnnk^pncx@&l6i38=&=u6c!x8d5l92!5'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todo.apps.TodoConfig',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'mysite.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Seoul'

USE_I18N = True

USE_L10N = True

USE_TZ = False


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

root/mysite/urls.py

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),

    path('', views.HomeView.as_view(), name='home')
]

root/mysite/views.py

from django.views.generic import TemplateView


class HomeView(TemplateView):
    template_name = 'home.html'
    

template html은 이전 프로젝트의 templates 폴더째로 복사해온다. (base.htmlhome.html이 들어있는 것)

그리고 실행환경을 구성하고 서버를 실행한다.

오류가 뜬다면 base.html을 아래 코드와 같이 수정한다.

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}home.html{% endblock %}</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css">
    <link rel="shortcut icon" href="{% static 'img/favicon.ico' %}">

    {% block extra-style %}{% endblock %}
</head>
<body style="padding-top: 90px;">


<!-- Main Menu -->
<nav class="navbar navbar-expand-sm navbar-dark bg-primary fixed-top">

    <span class="navbar-brand mx-5 mb-0 font-weight-bold font-italic">Vue-Django System</span>

    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item mx-1 btn btn-primary">
                <a class="nav-link text-white" href="{% url 'home' %}">Home</a></li>
            <li class="nav-item mx-1 btn btn-primary">
                <a class="nav-link text-white" href="{% url 'home' %}">Todo</a></li>
            <li class="nav-item mx-1 btn btn-primary">
                <a class="nav-link text-white" href="{% url 'home' %}">Blog(tobe)</a></li>

            <li class="nav-item dropdown mx-1 btn btn-primary">
                <a class="nav-link dropdown-toggle text-white" href="#" data-toggle="dropdown">Util</a>
                <div class="dropdown-menu">
                    <a class="dropdown-item" href="{% url 'admin:index' %}">Admin</a>
                    <div class="dropdown-divider"></div>
                </div>
            </li>
        </ul>

        <form class="form-inline my-2">
            <input class="form-control mr-sm-2" type="search" placeholder="Search">
        </form>

        <ul class="navbar-nav ml-5 mr-5">
            <li class="nav-item dropdown mx-1 btn btn-primary">
                <a class="nav-link dropdown-toggle text-white" href="#" data-toggle="dropdown">
                    <i class="fas fa-user"></i>&nbsp; Anonymous &nbsp;</a>
                <div class="dropdown-menu">
                    <a class="dropdown-item" href="{% url 'home' %}">Login</a>
                    <a class="dropdown-item" href="{% url 'home' %}">Register</a>
                </div>
            </li>
        </ul>

    </div>
</nav>

<div class="container">
    {% block content %}{% endblock %}
</div>

{% block footer %}{% endblock %}
<!-- Bootstrap core JavaScript -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

{% block extra-script %}{% endblock %}

</body>
</html>

또한 이전 프로젝트에서 이미지 등 에셋이 들어있는 static 폴더도 복사 붙여넣기한다.


GitHub Source

👉🏻깃허브 소스

profile
Full-stack Engineer. email - corner3499@kakao.com,

0개의 댓글