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

目录
  • 1. 前言
  • 2. 环境准备
  • 3. 创建 Django 项目
  • 4. 创建 Vue.js 前端项目
  • 5. 解决跨域问题
  • 6. 整合 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构建项目内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解django模板与vue.js冲突问题

    问题: django模板与vue.js的变量都是使用"{{"和"}}"包裹起来的,在渲染django模板时会先替代掉所有的"{{"和"}}"及被包裹在其中的内容,使得vue.js没有使用"{{"."}}"来绑定变量. 处理方法: 方法1:修改vue.js的默认的绑定符号 Vue.config.delimiters = ["[[", "]]"]; 执

  • Django+Vue.js搭建前后端分离项目的示例

    在写这篇文章的时候,顺带学习了一下关于Markdown的使用方法. 笔者是个渣渣,一切都是自己在摸索的学着,所以也谈不上什么体系.系统学习.在这里主要是为了实现把项目前后端分离开. 这里假设你的电脑上所需的django.vue.js已经有了,如果没有,往下拉就是vue.js的安装流程.django前面写过了,就不赘述了. 一,正常搭建前后端分离项目流程 1.创建django项目 命令: django-admin startproject ulb_manager 结构: ├── manage.py

  • django中使用vue.js的要点总结

    有接口如下: http://127.0.0.1:8000/info/schemes/ 返回json数据: [ { "name": "(山上双人标准间)黄山经典二日游(魅力黄山,日出云海,人间仙境,春暖花开)", "day": 2, "night": 1, "favorites": 0, "score_avg": 4, "photo_url": "/media

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

    目录 1. 前言 2. 环境准备 3. 创建 Django 项目 4. 创建 Vue.js 前端项目 5. 解决跨域问题 6. 整合 Django 和 Vue.js 前端 1. 前言 本篇将基于Django + Vue.js,手把手教大家快速的实现一个前后端分离的Web项目. 2. 环境准备 Python 3.6.1 Mysql 5.7.23 Pycharm (专业版) Node 3. 创建 Django 项目 创建完成后,目录结构如下所示 使用 Navicat 工具创建数据库 DjangoVu

  • 手把手教你写一个vue全局注册的Toast的实现

    目录 前言: 我们先思考下面的问题: 首先: 然后: 后来: 再且: 前言: 前几天客户经理不让我用某饿了么之类的UI库做一个轻提示之类的组件,当时一想我是饿了么战士,怎么会写哪个东西,然后我就想着用个alert糊弄过去,但是不行,然后我就细琢磨,发现Vue有个非常不错的Vue.extend. 经过一番努力,我学会了,可能是以前学的时候马虎漏掉了.不过问题不大,还能肝. 我们先思考下面的问题: 在写vue项目的时候啊,我们有了初始化的根实例之后,页面之间都是通过router进行管理,组件也是通过

  • 手把手教你搭建一个vue项目的完整步骤

    目录 一.环境准备 1.安装node.js 2.检查node.js版本 3.为了提高我们的效率,可以使用淘宝的镜像源 二.搭建vue环境 1.全局安装vue-cli 三.创建vue项目 1.用cmd命令创建项目 1.1创建文件 1.2选择配置信息 1.3选择版本 1.4路径模式选择 1.5语法代码格式检查 1.6第三方文件存在的方式 1.7是否保存本次配置信息(保存预设) 1.8创建成功 1.9运行 1.10启动 1.11停止服务 2.用vue资源管理器创建 2.1进入vue资源管理器界面(vu

  • Vue.js快速入门教程

    像AngularJS这种前端框架可以让我们非常方便地开发出强大的单页应用,然而有时候Angular这种大型框架对于我们的项目来说过于庞大,很多功能不一定会用到.这时候我们就需要评估一下使用它的必要性了.如果我们仅仅需要在一个简单的网页里添加屈指可数的几个功能,那么用Angular就太麻烦了,必要的安装.配置.编写路由和设计控制器等等工作显得过于繁琐. 这时候我们需要一个更加轻量级的解决方案.Vue.js就是一个不错的选择.Vue.js是一个专注于视图模型(ViewModal)的框架.视图模型是U

  • 基于vue.js快速搭建图书管理平台

    Vue.js是当下很火的一个JavaScript MVVM(Model-View-ViewModel)库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快速地上手并使用Vue.js. 上一期简单讲解了vue的基本语法,这一次我们做一个小项目,搭建一个简单的图书管理平台,能够让我们更深刻的理解这门语言的妙用. 1.DEMO样式 首先我们需要搭建一个简单的demo样式,推荐大家使用bootstrap,可以很快的搭建出一个清

  • Vue.js快速入门实例教程

    什么是vue vue是法语中视图的意思,Vue.js是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API. 一.基本结构 index.html代码: <script src="../vue.js"></script> <div id="app"> {{ message }} </div> <script src="app.js"></script> <

  • 用Go+Vue.js快速搭建一个Web应用(初级demo)

    Vue.js做为目前前端最热门的库之一,为快速构建并开发前端项目多了一种思维模式.本文给大家介绍用Go+Vue.js快速搭建一个Web应用(初级demo). 环境准备: 1. 安装go语言,配置go开发环境: 2. 安装node.js以及npm环境: Gin的使用: 为了快速搭建后端应用,采用了Gin作为Web框架.Gin是用Golang实现的一种Web框架,api非常友好,且拥有出色的路由性能和详细的错误提示,如果你想快速开发一个高性能的生产环境,Gin是一个不错的选择. 下载和安装Gin:

  • 手把手教你用Django执行原生SQL的方法

    前言 Hey,各位小伙伴,这次怎么来玩一下,如何使用Django执行原生SQL. 我们都知道,Python在web界的扛把子--Django,可谓是集大成为统一,各种各样的插件.forms组件.model模型.Admin后台等等,后面我会专门出文章娓娓道来,反正就是一个字,NB. 本次就来学一下,如何在Django执行原生语句. 起因 在使用Django时,一般情况下,我们使用Django自带的model查询是没有问题的,基本能满足80%的问题 但是,但是,那20%就不要了吗???肯定不行哎,小

  • 手把手教你实现Python连接数据库并快速取数的工具

    目录 前言 一.数据库连接类 二.数据提取主函数模块 在数据生产应用部门,取数分析是一个很常见的需求,实际上业务人员需求时刻变化,最高效的方式是让业务部门自己来取,减少不必要的重复劳动,一般情况下,业务部门数据库表结构一般是固定的,根据实际业务将取数需求做成sql 脚本,快速完成数据获取---授人以渔的方式,提供平台或工具 那如何实现一个自助取数查询工具? 基于底层数据来开发不难,无非是将用户输入变量作为筛选条件,将参数映射到 sql 语句,并生成一个 sql 语句然后再去数据库执行 前言 最后

  • 手把手教你拿捏vue cale()计算函数使用

    目录 前言 cale()是什么 基本使用 灵活使用 注意 兼容性 结尾 前言 最近项目中遇到calc()方法不生效问题,本着究其所以然的想法,彻底查了一下calc的方法及使用,还有为什么项目中使用不生效的问题,最后总结出此文,解决方法放在结尾了 cale()是什么 calc是英文单词calculate的缩写,其实主要用于对项目中一些单位的计算,这里的计算是在calc()函数里面填充表达式去计算,它会返回具体的值 基本使用 平常我们项目中遇到最多的就是一些普通计算了比如: <body> <

随机推荐