• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    手把手教你使用Django + Vue.js 快速构建项目

    1. 前言

    本篇将基于Django + Vue.js,手把手教大家快速的实现一个前后端分离的Web项目。

    2. 环境准备

    1.  Python 3.6.1
    2. Mysql 5.7.23
    3. Pycharm (专业版)
    4. Node

    3. 创建 Django 项目

    创建完成后,目录结构如下所示


    使用 Navicat 工具创建数据库 DjangoVue


    安装 mysqlclient 库


    配置 settings.py 文件,配置 Mysql 数据库引擎

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'DjangoVue',
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': '127.0.0.1',
        }
    }
    

    执行同步操作,将数据迁移到 Mysql


    启动 Django Server ,验证默认配置是否正常

    python manage.py runserver 0.0.0.0:8000


    打开浏览器,访问 http://localhost:8000


    创建一个 app 作为项目后端

    python manage.py startapp backend

    创建完成后,目录结构如下所示

    把 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='创建时间')
    
        def __unicode__(self):
            return self.bookName
    
        def __str__(self):
            return self.bookName
    
    

    根据修改创建迁移文件,并应用这些修改到数据库中

    # 创建迁移文件
    python manage.py makemigrations
    # 应用修改到数据库
    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='书名')
        createTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    
        def __unicode__(self):
            return self.bookName
    
        def __str__(self):
            return self.bookName
    
        class Meta:
            db_table = 'backend_book'
    
    

    在 backend/views 里我们新增两个接口,一个返回所有的书籍列表,一个往数据库里添加一条book数据。

    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


    4. 创建 Vue.js 前端项目

    使用 node 自带的 npm 包管理器安装 vue 和相关模块。推荐使用淘宝的 cnpm 命令行工具代替默认的 npm。

    npm install -g cnpm --registry=https://registry.npm.taobao.org
    

    安装 vue.js

    cnpm install -g vue

    安装vue-cli脚手架工具(vue-cli是官方脚手架工具,能迅速帮你搭建起vue项目的框架)

    cnpm install -g vue-cli

    在 djangoVue 项目根目录下,新建一个前端工程目录

    vue-init webpack frontend

    在创建项目的过程中会弹出一些与项目相关的选项需要回答,按照真实情况进行输入即可,如下:

    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
    回车;


    安装 vue 依赖模块

    cd frontend
    cnpm install
    cnpm install vue-resource
    cnpm install element-ui
    

    现在整个文件目录结构如下


    在 frontend 目录 src 下包含入口文件 main.js,入口组件 App.vue 等。后缀为 vue 的是 Vue.js 框架定义的单文件组件,一个文件包含且仅包含三块内容,如下:

    1. template>/template > 前端渲染的模板
    2. 专为此模板写渲染逻辑的 script>/script>
    3. 专为此模板写样式的 style>/style>

    在 src/components 文件夹下新建一个名为 Home.vue 的组件,通过调用之前在 Django 上写好的 api,实现添加书籍和展示书籍信息的功能。在样式组件上我们使用了饿了么团队推出的 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 自带的服务器,自动打开浏览器,如下页面:

    5. 解决跨域问题

    此时出现了一个问题,数据是空的,打开开发者工具,发现有错误。因为我们使用 VueJS 的开发环境脱离了 Django 环境,访问 Django 写的 API,出现了跨域问题,有两种方法解决,一种是在 VueJS 层上做转发(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
    

    至此,页面上有数据了,如下:

    新增书籍,如填入:“Django从入门到放弃”,新增的书籍信息会实时反映到页面的列表中,这得益于Vue.js的数据双向绑定特性。

    6. 整合 Django 和 Vue.js 前端

    目前我们已经分别完成了 Django 后端和 Vue.js 前端工程的创建和编写,但实际上它们是运行在各自的服务器上,和我们的要求是不一致的。

    在前端工程 frontend 目录下,输入 npm run build,如果项目没有错误的话,就能够看到所有的组件、css、图片等都被 webpack 自动打包到 dist 目录下了,里面有一个 index.html 和一个文件夹 static。

    修改 djangoVue 下的 urls ,使用通用视图创建最简单的模板控制器,访问 『/』时直接返回 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 的模板系统,所以需要配置一下模板使 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',
                ],
            },
        },
    ]
    

    配置静态文件的搜索路径。

    # Add for vuejs
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "frontend/dist/static"),
    ]
    

    配置完成,启动 Django 服务 python manage.py runserver,就能够看到我们的前端页面在浏览器上展现:


    此时服务的端口已经是 Django 服务的 8000 而不是 node 服务的 8080 了,说明我们已经成功通过 Django 集成了 Vue 前端工程。

    到此这篇关于手把手教你使用Django + Vue.js 快速构建项目的文章就介绍到这了,更多相关Django Vue.js构建项目内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • 详解django模板与vue.js冲突问题
    • django中使用vue.js的要点总结
    • Django+Vue.js搭建前后端分离项目的示例
    上一篇:教你使用一行Python代码玩遍童年的小游戏
    下一篇:利用Python读取微信朋友圈的多种方法总结
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    手把手教你使用Django + Vue.js 快速构建项目 手把手,教你,使用,Django,