目錄
- 1. 前言
- 2. 環(huán)境準備
- 3. 創(chuàng)建 Django 項目
- 4. 創(chuàng)建 Vue.js 前端項目
- 5. 解決跨域問題
- 6. 整合 Django 和 Vue.js 前端
1. 前言
本篇將基于Django + Vue.js,手把手教大家快速的實現(xiàn)一個前后端分離的Web項目。
2. 環(huán)境準備
- Python 3.6.1
- Mysql 5.7.23
- Pycharm (專業(yè)版)
- Node
3. 創(chuàng)建 Django 項目
![](/d/20211017/2204dc87fad3bc107c45cf1f92e87a71.gif)
創(chuàng)建完成后,目錄結(jié)構(gòu)如下所示
![](/d/20211017/df122ade088247448ee2abaedbd9d746.gif)
使用 Navicat 工具創(chuàng)建數(shù)據(jù)庫 DjangoVue
![](/d/20211017/389ed9ebd98c80c1d329f65f410b6b9e.gif)
安裝 mysqlclient 庫
![](/d/20211017/8a60975927875ae278a202ab131da935.gif)
![](/d/20211017/c0c25d63f6be2b1ea90d04c6592ebd5e.gif)
配置 settings.py 文件,配置 Mysql 數(shù)據(jù)庫引擎
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'DjangoVue',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
}
}
執(zhí)行同步操作,將數(shù)據(jù)遷移到 Mysql
![](/d/20211017/1b069cb93838e1edc94bcba01a8689ab.gif)
啟動 Django Server ,驗證默認配置是否正常
python manage.py runserver 0.0.0.0:8000
![](/d/20211017/4e6fd2cce64be40d9d89775f6b3e54e2.gif)
打開瀏覽器,訪問 http://localhost:8000
![](/d/20211017/42ca2ef7c7825d32963b32680e2897e2.gif)
創(chuàng)建一個 app 作為項目后端
python manage.py startapp backend
創(chuàng)建完成后,目錄結(jié)構(gòu)如下所示
![](/d/20211017/1121b51617361b44d81c5901ebe651c3.gif)
把 backend 加入到 settings.py 文件中的 INSTALLED_APPS 列表里
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'backend'
]
在 backend/models.py 里寫一個簡單 model 如下
from django.db import models
# Create your models here.
class Book(models.Model):
# 如果沒有指定主鍵的話Django會自動新增一個自增id作為主鍵
bookName = models.CharField(max_length=128, verbose_name='書名')
createTime = models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時間')
def __unicode__(self):
return self.bookName
def __str__(self):
return self.bookName
根據(jù)修改創(chuàng)建遷移文件,并應用這些修改到數(shù)據(jù)庫中
# 創(chuàng)建遷移文件
python manage.py makemigrations
# 應用修改到數(shù)據(jù)庫
python manage.py migrate
![](/d/20211017/257ec07765b15225a771a364ebe628c2.gif)
Django 生成的表名將以 app 名加上 model 中的類名組合而成,也可以自定義表名,如下
from django.db import models
# Create your models here.
class Book(models.Model):
bookName = models.CharField(max_length=128, verbose_name='書名')
createTime = models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時間')
def __unicode__(self):
return self.bookName
def __str__(self):
return self.bookName
class Meta:
db_table = 'backend_book'
在 backend/views 里我們新增兩個接口,一個返回所有的書籍列表,一個往數(shù)據(jù)庫里添加一條book數(shù)據(jù)。
import json
from django.core import serializers
from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.http import require_http_methods
from backend.models import Book
@require_http_methods(["GET"])
def add_book(request):
response = {}
try:
book_name = request.GET.get('book_name')
book = Book(bookName=book_name)
book.save()
response['respMsg'] = 'success'
response['respCode'] = '000000'
except Exception as e:
response['respMsg'] = str(e)
response['respCode'] = '999999'
return JsonResponse(response)
@require_http_methods(["GET"])
def show_books(request):
response = {}
try:
books = Book.objects.filter()
response['list'] = json.loads(serializers.serialize("json", books))
response['respMsg'] = 'success'
response['respCode'] = '000000'
except Exception as e:
response['respMsg'] = str(e)
response['respCode'] = '999999'
return JsonResponse(response)
在 backend 目錄下,新增一個 urls.py 文件,把我們新增的兩個接口添加到路由里
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
File Name : urls.py
Description :
Author : FHQI
date : 2021-08-19
-------------------------------------------------
"""
from django.conf.urls import url
from backend.views import add_book, show_books
urlpatterns = [
url("add_book", add_book, ),
url("show_books", show_books, ),
]
最后要把backend 下的 urls 添加到項目 djangoVue 下的 urls 中,才算完成路由
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('backend.urls')),
]
重新啟動服務,測試一下剛才寫的兩個接口
python manage.py runserver 0.0.0.0:8000
![](/d/20211017/092012012da7b55e0b3188d6e3105f4b.gif)
![](/d/20211017/cc68b52af82680bf3dbba98297dc4cbf.gif)
4. 創(chuàng)建 Vue.js 前端項目
使用 node 自帶的 npm 包管理器安裝 vue 和相關模塊。推薦使用淘寶的 cnpm 命令行工具代替默認的 npm。
npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝 vue.js
安裝vue-cli腳手架工具(vue-cli是官方腳手架工具,能迅速幫你搭建起vue項目的框架)
在 djangoVue 項目根目錄下,新建一個前端工程目錄
vue-init webpack frontend
在創(chuàng)建項目的過程中會彈出一些與項目相關的選項需要回答,按照真實情況進行輸入即可,如下:
Project name(工程名):回車
Project description(工程介紹):回車
Author:作者名 :回車
Vue build ==> (是否安裝編譯器)runtime-compiler、 runtime-only 都是打包方式,第二個效率更高;
Install vue-router ==> 是否要安裝 vue-router,項目中肯定要使用到路由,所以Y 回車;
Use ESLint to lint your code ==> 是否需要ESLint檢測代碼,目前我們不需要所以 n 回車;
Set up unit tests ==> 是否安裝 單元測試工具 目前我們不需要 所以 n 回車;
Setup e2e tests with Nightwatch ==>是否需要端到端測試工具目前我們不需要所以n回車;
Should we run npm install for you after the project has been created? (recommended) (Use arrow keys)==> 安裝依賴npm install
回車;
![](/d/20211017/ce2fbe74107df0597efb1202f8e3bc85.gif)
安裝 vue 依賴模塊
cd frontend
cnpm install
cnpm install vue-resource
cnpm install element-ui
現(xiàn)在整個文件目錄結(jié)構(gòu)如下
![](/d/20211017/b7ebbc52828f9429e0916494e23402ec.gif)
在 frontend 目錄 src 下包含入口文件 main.js,入口組件 App.vue 等。后綴為 vue 的是 Vue.js 框架定義的單文件組件,一個文件包含且僅包含三塊內(nèi)容,如下:
1. template>/template > 前端渲染的模板
2. 專為此模板寫渲染邏輯的 script>/script>
3. 專為此模板寫樣式的 style>/style>
在 src/components 文件夾下新建一個名為 Home.vue 的組件,通過調(diào)用之前在 Django 上寫好的 api,實現(xiàn)添加書籍和展示書籍信息的功能。在樣式組件上我們使用了餓了么團隊推出的 element-ui,這是一套專門匹配 Vue.js 框架的功能樣式組件。由于組件的編碼涉及到了很多 js、html、css 的知識,并不是本文的重點,因此在此只貼出部分代碼。
template>
div class="home">
el-row display="margin-top:10px">
el-input v-model="input" placeholder="請輸入書名" style="display:inline-table; width: 30%; float:left">/el-input>
el-button type="primary" @click="addBook()" style="float:left; margin: 2px;">新增/el-button>
/el-row>
el-row>
el-table :data="bookList" style="width: 100%" border>
el-table-column prop="id" label="編號" min-width="100">
template slot-scope="scope"> {{ scope.row.pk }} /template>
/el-table-column>
el-table-column prop="bookName" label="書名" min-width="100">
template slot-scope="scope"> {{ scope.row.fields.bookName }} /template>
/el-table-column>
el-table-column prop="createTime" label="添加時間" min-width="100">
template slot-scope="scope"> {{ scope.row.fields.createTime }} /template>
/el-table-column>
/el-table>
/el-row>
/div>
/template>
script>
export default {
name: 'home',
data () {
return {
input: '',
bookList: []
}
},
mounted: function () {
this.showBooks()
},
methods: {
addBook () {
this.$http.get('http://127.0.0.1:8000/api/add_book?book_name=' + this.input)
.then((response) => {
var res = JSON.parse(response.bodyText)
if (res.respCode === '000000') {
this.showBooks()
} else {
this.$message.error('新增書籍失敗,請重試')
console.log(res['respMsg'])
}
})
},
showBooks () {
this.$http.get('http://127.0.0.1:8000/api/show_books')
.then((response) => {
var res = JSON.parse(response.bodyText)
console.log(res)
if (res.respCode === '000000') {
this.bookList = res['list']
} else {
this.$message.error('查詢書籍失敗')
console.log(res['respMsg'])
}
})
}
}
}
/script>
style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
/style>
在 src/router 目錄的 index.js 中,把新建的 Home 組件,配置到 vue-router 路由中
import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/Home'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
// name: 'HelloWorld',
name: 'Home',
// component: HelloWorld
component: Home
}
]
})
在 src/main.js 文件中,導入 element-ui、vue-resource 庫。
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import VueResource from 'vue-resource'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
Vue.use(VueResource)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
在前端工程 frontend 目錄下,輸入 npm run dev
啟動 node 自帶的服務器,自動打開瀏覽器,如下頁面:
![](/d/20211017/e513fdbede48d169584f5d7b70baf6d5.gif)
5. 解決跨域問題
此時出現(xiàn)了一個問題,數(shù)據(jù)是空的,打開開發(fā)者工具,發(fā)現(xiàn)有錯誤。因為我們使用 VueJS 的開發(fā)環(huán)境脫離了 Django 環(huán)境,訪問 Django 寫的 API,出現(xiàn)了跨域問題,有兩種方法解決,一種是在 VueJS 層上做轉(zhuǎn)發(fā)(proxyTable),另一種是在 Django 層注入 header,這里使用后者,用 Django 的第三方包 django-cors-headers 來解決跨域問題。
pip install django-cors-headers
修改 settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # 添加1,注意中間件的添加順序
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True # 添加2
至此,頁面上有數(shù)據(jù)了,如下:
![](/d/20211017/336114f34ec05bec085b900614e13f2c.gif)
新增書籍,如填入:“Django從入門到放棄”,新增的書籍信息會實時反映到頁面的列表中,這得益于Vue.js的數(shù)據(jù)雙向綁定特性。
![](/d/20211017/312fb34a363ca151494b524cb3363326.gif)
6. 整合 Django 和 Vue.js 前端
目前我們已經(jīng)分別完成了 Django 后端和 Vue.js 前端工程的創(chuàng)建和編寫,但實際上它們是運行在各自的服務器上,和我們的要求是不一致的。
在前端工程 frontend 目錄下,輸入 npm run build
,如果項目沒有錯誤的話,就能夠看到所有的組件、css、圖片等都被 webpack 自動打包到 dist 目錄下了,里面有一個 index.html 和一個文件夾 static。
![](/d/20211017/01fe437c22946ceafaac1440e23ede6d.gif)
修改 djangoVue 下的 urls ,使用通用視圖創(chuàng)建最簡單的模板控制器,訪問 『/』時直接返回 index.html
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('backend.urls')),
path(r'', TemplateView.as_view(template_name="index.html")),
]
配置 Django 項目的模板搜索路徑。上一步使用了 Django 的模板系統(tǒng),所以需要配置一下模板使 Django 知道從哪里找到 index.html。修改 settings.py 文件,如下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [os.path.join(BASE_DIR, 'templates')],
'DIRS': [os.path.join(BASE_DIR, 'frontend/dist')],
'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',
],
},
},
]
配置靜態(tài)文件的搜索路徑。
# Add for vuejs
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "frontend/dist/static"),
]
配置完成,啟動 Django 服務 python manage.py runserver
,就能夠看到我們的前端頁面在瀏覽器上展現(xiàn):
![](/d/20211017/0769cadc439c401eed8677ee3185cfe3.gif)
此時服務的端口已經(jīng)是 Django 服務的 8000 而不是 node 服務的 8080 了,說明我們已經(jīng)成功通過 Django 集成了 Vue 前端工程。
到此這篇關于手把手教你使用Django + Vue.js 快速構(gòu)建項目的文章就介紹到這了,更多相關Django Vue.js構(gòu)建項目內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- 詳解django模板與vue.js沖突問題
- django中使用vue.js的要點總結(jié)
- Django+Vue.js搭建前后端分離項目的示例