最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

手把手教你使用Django + Vue.js 快速構(gòu)建項(xiàng)目

 更新時(shí)間:2021年08月22日 08:55:24   作者:三天不練手生  
本篇將基于Django + Vue.js,手把手教大家快速的實(shí)現(xiàn)一個(gè)前后端分離的Web項(xiàng)目。文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

1. 前言

本篇將基于Django + Vue.js,手把手教大家快速的實(shí)現(xiàn)一個(gè)前后端分離的Web項(xiàng)目。

2. 環(huán)境準(zhǔn)備

  1.  Python 3.6.1
  2. Mysql 5.7.23
  3. Pycharm (專業(yè)版)
  4. Node

3. 創(chuàng)建 Django 項(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)有指定主鍵的話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 中的類名組合而成,也可以自定義表名,如下

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

在這里插入圖片描述

在這里插入圖片描述

4. 創(chuàng)建 Vue.js 前端項(xiàng)目

使用 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(工程名):回車
Project description(工程介紹):回車
Author:作者名 :回車
Vue build ==> (是否安裝編譯器)runtime-compiler、 runtime-only 都是打包方式,第二個(gè)效率更高;
Install vue-router ==> 是否要安裝 vue-router,項(xiàng)目中肯定要使用到路由,所以Y 回車;
Use ESLint to lint your code ==> 是否需要ESLint檢測(cè)代碼,目前我們不需要所以 n 回車;
Set up unit tests ==> 是否安裝 單元測(cè)試工具 目前我們不需要 所以 n 回車;
Setup e2e tests with Nightwatch ==>是否需要端到端測(cè)試工具目前我們不需要所以n回車;
Should we run npm install for you after the project has been created? (recommended) (Use arrow keys)==> 安裝依賴npm install
回車;

在這里插入圖片描述

安裝 vue 依賴模塊

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. 專為此模板寫(xiě)渲染邏輯的 <script></script>
3. 專為此模板寫(xiě)樣式的 <style></style>

在 src/components 文件夾下新建一個(gè)名為 Home.vue 的組件,通過(guò)調(diào)用之前在 Django 上寫(xiě)好的 api,實(shí)現(xiàn)添加書(shū)籍和展示書(shū)籍信息的功能。在樣式組件上我們使用了餓了么團(tuán)隊(duì)推出的 element-ui,這是一套專門(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('查詢書(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è)面:

在這里插入圖片描述

5. 解決跨域問(wèn)題

此時(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ù)雙向綁定特性。

在這里插入圖片描述

6. 整合 Django 和 Vue.js 前端

目前我們已經(jīng)分別完成了 Django 后端和 Vue.js 前端工程的創(chuàng)建和編寫(xiě),但實(shí)際上它們是運(yùn)行在各自的服務(wù)器上,和我們的要求是不一致的。

在前端工程 frontend 目錄下,輸入 npm run build,如果項(xiàng)目沒(méi)有錯(cuò)誤的話,就能夠看到所有的組件、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)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用代理抓取網(wǎng)站圖片(多線程)

    Python使用代理抓取網(wǎng)站圖片(多線程)

    Python作為一門(mén)功能強(qiáng)大的腳本語(yǔ)言,經(jīng)常被用來(lái)寫(xiě)爬蟲(chóng)程序,下面是使用Python通過(guò)代理進(jìn)行多線程抓取圖片,算是一個(gè)簡(jiǎn)易的python多線程爬蟲(chóng)
    2014-03-03
  • python算法練習(xí)之抓交通肇事犯

    python算法練習(xí)之抓交通肇事犯

    這篇文章主要該大家分享python算法抓交通肇事犯得練習(xí),文章主要通過(guò)描述抓交通肇事犯得問(wèn)題然后確定程序框架將結(jié)果運(yùn)算出來(lái),下面來(lái)看詳細(xì)內(nèi)容吧,需要的朋友可以參考一下喲
    2021-10-10
  • Python引用類型和值類型的區(qū)別與使用解析

    Python引用類型和值類型的區(qū)別與使用解析

    這篇文章主要介紹了Python引用類型和值類型的區(qū)別與使用解析,需要的朋友可以參考下
    2017-10-10
  • Elasticsearch文檔索引基本操作增刪改查示例

    Elasticsearch文檔索引基本操作增刪改查示例

    這篇文章主要為答案及介紹了Elasticsearch文檔索引基本操作增刪改查示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Python輕松寫(xiě)個(gè)課堂隨機(jī)點(diǎn)名系統(tǒng)

    Python輕松寫(xiě)個(gè)課堂隨機(jī)點(diǎn)名系統(tǒng)

    現(xiàn)在的學(xué)生大部分都很積極,會(huì)主動(dòng)舉手回答問(wèn)題。但是,也會(huì)遇到一些不好的情況,比如年級(jí)越高主動(dòng)舉手的人越少,所以本文寫(xiě)了一個(gè)隨機(jī)的學(xué)生點(diǎn)名系統(tǒng)可以幫老師解決這些問(wèn)題
    2023-01-01
  • Matlab中如何實(shí)現(xiàn)將長(zhǎng)字符串換行寫(xiě)

    Matlab中如何實(shí)現(xiàn)將長(zhǎng)字符串換行寫(xiě)

    這篇文章主要介紹了Matlab中如何實(shí)現(xiàn)將長(zhǎng)字符串換行寫(xiě)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • python中的reduce內(nèi)建函數(shù)使用方法指南

    python中的reduce內(nèi)建函數(shù)使用方法指南

    python中的reduce內(nèi)建函數(shù)是一個(gè)二元操作函數(shù),他用來(lái)將一個(gè)數(shù)據(jù)集合(鏈表,元組等)中的所有數(shù)據(jù)進(jìn)行下列操作:用傳給reduce中的函數(shù) func()(必須是一個(gè)二元操作函數(shù))先對(duì)集合中的第1,2個(gè)數(shù)據(jù)進(jìn)行操作,得到的結(jié)果再與第三個(gè)數(shù)據(jù)用func()函數(shù)運(yùn)算,最后得到一個(gè)結(jié)果
    2014-08-08
  • 使用Python求解最大公約數(shù)的實(shí)現(xiàn)方法

    使用Python求解最大公約數(shù)的實(shí)現(xiàn)方法

    這篇文章主要介紹了使用Python求解最大公約數(shù)的實(shí)現(xiàn)方法,包括用Python表示歐幾里得算法和Stein算法的求解原理,需要的朋友可以參考下
    2015-08-08
  • python 實(shí)現(xiàn)GUI(圖形用戶界面)編程詳解

    python 實(shí)現(xiàn)GUI(圖形用戶界面)編程詳解

    今天小編就為大家分享一篇python 實(shí)現(xiàn)GUI(圖形用戶界面)編程詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Python實(shí)戰(zhàn)案例之可增刪改查的員工管理系統(tǒng)

    Python實(shí)戰(zhàn)案例之可增刪改查的員工管理系統(tǒng)

    本實(shí)戰(zhàn)案例主要對(duì)MySQL進(jìn)行一些基本操作,通過(guò)完成本實(shí)驗(yàn)任務(wù),要求學(xué)生熟練掌握MySQL的增刪改查,并對(duì)MySQL的增刪改查基本操作進(jìn)行管理員工的信息,需要的朋友跟著小編往下看吧
    2021-10-10

最新評(píng)論

日喀则市| 隆子县| 迭部县| 微山县| 安西县| 绥江县| 彰武县| 包头市| 门源| 伊金霍洛旗| 随州市| 修武县| 比如县| 西和县| 平和县| 凌海市| 噶尔县| 宣城市| 长乐市| 泽普县| 湛江市| 安达市| 丹凤县| 大新县| 锡林浩特市| 大埔区| 偃师市| 连南| 邹城市| 凤翔县| 六安市| 基隆市| 莱阳市| 通海县| 溧阳市| 徐闻县| 元朗区| 三河市| 冷水江市| 澳门| 吴川市|