本文用於學習django+vue.js實現web前後端分離協作開發。以一個新增和刪除資料庫書籍應用為例項。
django框架官方地址:https://www.djangoproject.com/
vue.js 框架官方地址:https://cn.vuejs.org/
一、構建django專案
1. 建立工程檔案和APP
建立django_vue
django-admin startproject django_vue
進入django_vue,建立虛擬環境django_vue_env
pip install virtualenv #安裝
virtualenv django_vue_env
啟用虛擬環境,並安裝django
source ./django_vue_env/bin/activate
安裝 django、後面用到的django-cors-headers(跨域)、requests
建立django app
python manage.py startapp app
我們的目錄應該是這樣的,appfront為vue專案會在後面建立。
資料庫我們使用預設sqlite3 即可,如需要變更可在setting.py中databases配置。
新增app到INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app'
]
新增資料庫模型,包含book_name和add_time用於記錄書籍名稱和新增時間。
from django.db import models
# Create your models here.
class Book(models.Model):
book_name = models.CharField(max_length=64)
add_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.book_name
做資料庫遷移
python manage.py makemigrations app
python manage.py migrate
編寫views.py新增 show_books 和add_book兩個api介面,通過JsonResponse將請求資料返回。
from django.shortcuts import render
# Create your views here.
# 需要匯入相關的模組
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.core import serializers
import requests
import json
from .models import Book
@require_http_methods(["GET"])
def add_book(request):
response = {}
try:
book = Book(book_name=request.GET.get('book_name'))
book.save()
response['msg'] = 'success'
response['error_num'] = 0
except Exception as e:
response['msg'] = str(e)
response['error_num'] = 1
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['msg'] = 'success'
response['error_num'] = 0
except Exception as e:
response['msg'] = str(e)
response['error_num'] = 1
return JsonResponse(response)
在django_vue目錄下urls.py新增api路由
from django.contrib import admin
from django.urls import path,include
import app.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('api/',include(app.urls)),
]
在app目錄下的urls.py新增檢視路由
from django.urls import path,re_path
# 匯入 myapp 應用的 views 檔案
from . import views
urlpatterns = [
re_path(r'add_book$', views.add_book),
re_path(r'show_books$', views.show_books)
]
重啟服務,通過curl命令測試api可用性,如下介面正常。
python manage.py runserver
curl http://127.0.0.1:8000/api/add_book?book_name=mylife
{"msg": "success", "error_num": 0}
curl http://127.0.0.1:8000/api/show_books
{"list": [ {"model": "app.book", "pk": 9, "fields": {"book_name": "mylife", "add_time": "2021-06-16T14:44:49.230Z"}}], "msg": "success", "error_num": 0}
django後端大致構建完成,接下來做vue前端。
一、構建vue專案
安裝vue初始化命令列工具vue-cli
npm install -g vue-cli
在django_vue目錄下構建前端工程appfront
,其中包含webpack工具。
vue-init webpack appfront
appfront目錄如下
安裝渲染element-ui
、vue-resource
npm install element-ui
npm install vue-resource
調整src/main.js如下
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.config.productionTip = false
Vue.use(ElementUI)
Vue.use(VueResource)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
在src/component
目錄下新建Home.vue
,包含showBooks
和addBook
兩個方法用於api查詢。
<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 scope="scope"> {{ scope.row.pk }} </template>
</el-table-column>
<el-table-column prop="book_name" label="書名" min-width="100">
<template scope="scope"> {{ scope.row.fields.book_name }} </template>
</el-table-column>
<el-table-column prop="add_time" label="新增時間" min-width="100">
<template scope="scope"> {{ scope.row.fields.add_time }} </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://139.198.114.148:8000/api/add_book?book_name=' + this.input)
.then((response) => {
var res = JSON.parse(response.bodyText)
if (res.error_num == 0) {
this.showBooks()
} else {
this.$message.error('新增書籍失敗,請重試')
console.log(res['msg'])
}
})
},
showBooks(){
this.$http.get('http://139.198.114.148:8000/api/show_books')
.then((response) => {
var res = JSON.parse(response.bodyText)
console.log(res)
if (res.error_num == 0) {
this.bookList = res['list']
} else {
this.$message.error('查詢書籍失敗')
console.log(res['msg'])
}
})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<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>
我們通過django-cors-headers處理跨域問題
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'corsheaders', //新增app
]
新增中介軟體corsheaders.middleware.CorsMiddleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
在setting.py中配置跨域規則
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
npm run dev
啟動node伺服器
通過npm run build
打包前端到dist目錄,用於後續django連結。
三、django連結到前端
調整django_vue目錄下路由urls.py如下
from django.contrib import admin
from django.urls import path,include
from django.views.generic import TemplateView //匯入通用檢視
import app.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('api/',include(app.urls)),
path('',TemplateView.as_view(template_name="index.html")), //路由到index.html
]
在setting.py下新增靜態檔案地址
STATICFILES_DIRS = [(os.path.join(BASE_DIR,'appfront/dist/static'))]
啟動django 服務
python manage.py runserver
訪問我們的django地址,此時django已連結到前端
參考:https://github.com/rogerlh/django_with_vue
NEXT
- django-rest-framework 建立restful api
- django wsgi的應用
文章有不足的地方歡迎在評論區指出。
歡迎收藏、點贊、提問。關注頂級飲水機管理員,除了管燒熱水,有時還做點別的。