本篇將基于Django + Vue.js,手把手教大家快速的實(shí)現(xiàn)一個(gè)前后端分離的Web項(xiàng)目。
創(chuàng)建完成后,目錄結(jié)構(gòu)如下所示
使用 Navicat 工具創(chuàng)建數(shù)據(jù)庫(kù) DjangoVue
安裝 mysqlclient 庫(kù)
配置 settings.py 文件,配置 Mysql 數(shù)據(jù)庫(kù)引擎
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'DjangoVue', 'USER': 'root', 'PASSWORD': 'root', 'HOST': '127.0.0.1', } }
執(zhí)行同步操作,將數(shù)據(jù)遷移到 Mysql
啟動(dòng) Django Server ,驗(yàn)證默認(rèn)配置是否正常
python manage.py runserver 0.0.0.0:8000
打開(kāi)瀏覽器,訪問(wèn) http://localhost:8000
創(chuàng)建一個(gè) app 作為項(xiàng)目后端
python manage.py startapp backend
創(chuàng)建完成后,目錄結(jié)構(gòu)如下所示
把 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 里寫(xiě)一個(gè)簡(jiǎn)單 model 如下
from django.db import models # Create your models here. class Book(models.Model): # 如果沒(méi)有指定主鍵的話(huà)Django會(huì)自動(dòng)新增一個(gè)自增id作為主鍵 bookName = models.CharField(max_length=128, verbose_name='書(shū)名') createTime = models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時(shí)間') def __unicode__(self): return self.bookName def __str__(self): return self.bookName
根據(jù)修改創(chuàng)建遷移文件,并應(yīng)用這些修改到數(shù)據(jù)庫(kù)中
# 創(chuàng)建遷移文件 python manage.py makemigrations # 應(yīng)用修改到數(shù)據(jù)庫(kù) python manage.py migrate
Django 生成的表名將以 app 名加上 model 中的類(lèi)名組合而成,也可以自定義表名,如下
from django.db import models # Create your models here. class Book(models.Model): bookName = models.CharField(max_length=128, verbose_name='書(shū)名') createTime = models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時(shí)間') def __unicode__(self): return self.bookName def __str__(self): return self.bookName class Meta: db_table = 'backend_book'
在 backend/views 里我們新增兩個(gè)接口,一個(gè)返回所有的書(shū)籍列表,一個(gè)往數(shù)據(jù)庫(kù)里添加一條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 目錄下,新增一個(gè) urls.py 文件,把我們新增的兩個(gè)接口添加到路由里
# -*- 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 添加到項(xiàng)目 djangoVue 下的 urls 中,才算完成路由
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('backend.urls')), ]
重新啟動(dòng)服務(wù),測(cè)試一下剛才寫(xiě)的兩個(gè)接口
python manage.py runserver 0.0.0.0:8000
使用 node 自帶的 npm 包管理器安裝 vue 和相關(guān)模塊。推薦使用淘寶的 cnpm 命令行工具代替默認(rèn)的 npm。
npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝 vue.js
cnpm install -g vue
安裝vue-cli腳手架工具(vue-cli是官方腳手架工具,能迅速幫你搭建起vue項(xiàng)目的框架)
cnpm install -g vue-cli
在 djangoVue 項(xiàng)目根目錄下,新建一個(gè)前端工程目錄
vue-init webpack frontend
在創(chuàng)建項(xiàng)目的過(guò)程中會(huì)彈出一些與項(xiàng)目相關(guān)的選項(xiàng)需要回答,按照真實(shí)情況進(jìn)行輸入即可,如下:
Project name(工程名):回車(chē)
Project description(工程介紹):回車(chē)
Author:作者名 :回車(chē)
Vue build ==> (是否安裝編譯器)runtime-compiler、 runtime-only 都是打包方式,第二個(gè)效率更高;
Install vue-router ==> 是否要安裝 vue-router,項(xiàng)目中肯定要使用到路由,所以Y 回車(chē);
Use ESLint to lint your code ==> 是否需要ESLint檢測(cè)代碼,目前我們不需要所以 n 回車(chē);
Set up unit tests ==> 是否安裝 單元測(cè)試工具 目前我們不需要 所以 n 回車(chē);
Setup e2e tests with Nightwatch ==>是否需要端到端測(cè)試工具目前我們不需要所以n回車(chē);
Should we run npm install for you after the project has been created? (recommended) (Use arrow keys)==> 安裝依賴(lài)npm install
回車(chē);
安裝 vue 依賴(lài)模塊
cd frontend cnpm install cnpm install vue-resource cnpm install element-ui
現(xiàn)在整個(gè)文件目錄結(jié)構(gòu)如下
在 frontend 目錄 src 下包含入口文件 main.js,入口組件 App.vue 等。后綴為 vue 的是 Vue.js 框架定義的單文件組件,一個(gè)文件包含且僅包含三塊內(nèi)容,如下:
1. template>/template > 前端渲染的模板
2. 專(zhuān)為此模板寫(xiě)渲染邏輯的 script>/script>
3. 專(zhuān)為此模板寫(xiě)樣式的 style>/style>
在 src/components 文件夾下新建一個(gè)名為 Home.vue 的組件,通過(guò)調(diào)用之前在 Django 上寫(xiě)好的 api,實(shí)現(xiàn)添加書(shū)籍和展示書(shū)籍信息的功能。在樣式組件上我們使用了餓了么團(tuán)隊(duì)推出的 element-ui,這是一套專(zhuān)門(mén)匹配 Vue.js 框架的功能樣式組件。由于組件的編碼涉及到了很多 js、html、css 的知識(shí),并不是本文的重點(diǎn),因此在此只貼出部分代碼。
template> div class="home"> el-row display="margin-top:10px"> el-input v-model="input" placeholder="請(qǐng)輸入書(shū)名" 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="編號(hào)" min-width="100"> template slot-scope="scope"> {{ scope.row.pk }} /template> /el-table-column> el-table-column prop="bookName" label="書(shū)名" min-width="100"> template slot-scope="scope"> {{ scope.row.fields.bookName }} /template> /el-table-column> el-table-column prop="createTime" label="添加時(shí)間" 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('新增書(shū)籍失敗,請(qǐng)重試') 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('查詢(xún)書(shū)籍失敗') 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 文件中,導(dǎo)入 element-ui、vue-resource 庫(kù)。
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
啟動(dòng) node 自帶的服務(wù)器,自動(dòng)打開(kāi)瀏覽器,如下頁(yè)面:
此時(shí)出現(xiàn)了一個(gè)問(wèn)題,數(shù)據(jù)是空的,打開(kāi)開(kāi)發(fā)者工具,發(fā)現(xiàn)有錯(cuò)誤。因?yàn)槲覀兪褂?VueJS 的開(kāi)發(fā)環(huán)境脫離了 Django 環(huán)境,訪問(wèn) Django 寫(xiě)的 API,出現(xiàn)了跨域問(wèn)題,有兩種方法解決,一種是在 VueJS 層上做轉(zhuǎn)發(fā)(proxyTable),另一種是在 Django 層注入 header,這里使用后者,用 Django 的第三方包 django-cors-headers 來(lái)解決跨域問(wèn)題。
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
至此,頁(yè)面上有數(shù)據(jù)了,如下:
新增書(shū)籍,如填入:“Django從入門(mén)到放棄”,新增的書(shū)籍信息會(huì)實(shí)時(shí)反映到頁(yè)面的列表中,這得益于Vue.js的數(shù)據(jù)雙向綁定特性。
目前我們已經(jīng)分別完成了 Django 后端和 Vue.js 前端工程的創(chuàng)建和編寫(xiě),但實(shí)際上它們是運(yùn)行在各自的服務(wù)器上,和我們的要求是不一致的。
在前端工程 frontend 目錄下,輸入 npm run build
,如果項(xiàng)目沒(méi)有錯(cuò)誤的話(huà),就能夠看到所有的組件、css、圖片等都被 webpack 自動(dòng)打包到 dist 目錄下了,里面有一個(gè) index.html 和一個(gè)文件夾 static。
修改 djangoVue 下的 urls ,使用通用視圖創(chuàng)建最簡(jiǎn)單的模板控制器,訪問(wèn) 『/』時(shí)直接返回 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 項(xiàng)目的模板搜索路徑。上一步使用了 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"), ]
配置完成,啟動(dòng) Django 服務(wù) python manage.py runserver
,就能夠看到我們的前端頁(yè)面在瀏覽器上展現(xiàn):
此時(shí)服務(wù)的端口已經(jīng)是 Django 服務(wù)的 8000 而不是 node 服務(wù)的 8080 了,說(shuō)明我們已經(jīng)成功通過(guò) Django 集成了 Vue 前端工程。
到此這篇關(guān)于手把手教你使用Django + Vue.js 快速構(gòu)建項(xiàng)目的文章就介紹到這了,更多相關(guān)Django Vue.js構(gòu)建項(xiàng)目?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:盤(pán)錦 大同 漯河 寧夏 南平 林芝 海南 普洱
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《手把手教你使用Django + Vue.js 快速構(gòu)建項(xiàng)目》,本文關(guān)鍵詞 手把手,教你,使用,Django,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。