一、背景
主要介绍如何使用后端Django + 前端Vue 的技术栈快速地搭建起一套web项目的框架。
为什么使用Django和Vue?
Django是Python体系下最成熟的web框架之一,由于Python语言的易用性和受众面广,Django框架也因其能够快速开发网站应用的特性成为了中小型网站开发框架首选。
Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
使用Vue作为前端框架,代替Django本身较为孱弱的模板引擎,Django则作为服务端提供api接口,使得前后端实现完全分离,更适合单页应用的开发构建。
二、环境准备
Django:
Python 3.7
Django 2.2.5 使用python自带的pip安装器安装。命令:pip install django即可 安装最新版本的django
Mysql 5.7 安装连接Mysql的库 pip3 install pymysql
Vue:
Node.js v14.3.0
官网下载:http://nodejs.cn
有关Vue的模块(包括vue)我们都使用node自带的npm包管理器安装
首先使用Django来搭建web后端api框架。
1、mac os系统上执行pip3安装:
$pip3 install Django
2、查看安装是否OK:
$python3 -m django --version
3、创建工程(工程名为ATS_Web)
$django-admin startproject ATS_Web
如果命令不存在,寻找到django-admin,用下面的命令:
$ python3 /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/bin/django-admin.py startproject ATS_Web
4、创建应用(一个工程有多个应用)
$cd /Users/mac/ATS_Web
$python3 manage.py startapp myApp
5、在ATS_Web下的settings.py配置文件中,把默认的sqllite3数据库换成我们的mysql数据库, 并把app加入到installed_apps列表里:
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ats_test',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
}
}
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myApp', #add
]
在 python3 中,连接MySQL的库为pymysql 库,使用pip3 install pymysql 进行安装,直接导入即可使用, 但是在 Django 中,连接数据库时使用的是 MySQLdb 库,需要在setting.py中导入:
import pymysql
pymysql.install_as_MySQLdb()
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)
7、 在app目录下的views里我们新增两个接口,一个是show_books返回所有的书籍列表(通过JsonResponse返回能被前端识别的json格式数据),另一个是add_book接受一个get请求,往数据库里添加一条book数据:
from django.shortcuts import render
from django.http import JsonResponse
from django.core import serializers
from myApp.models import Book
import json
# Create your views here.
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)
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)
8、在project下的urls.py中,添加两个url:
from django.contrib import admin
from django.urls import path
from myApp import views as BookView
urlpatterns = [
path('admin/', admin.site.urls),
path('add_book/',BookView.add_book),
path('show_books/',BookView.show_books),
]
9、创建mysql数据库ats_test,迁移表,在项目的根目录,输入命令:
$python manage.py makemigrations
$python manage.py migrate
$python manage.py makemigrations myapp
$python manage.py migrate
启动项目 $python manage.py runserver
在浏览器中测试接口:
http://localhost:8000/add_book/?book_name=test
http://localhost:8000/show_books/
没问题能打开之后,恭喜你,Django这部分构建完成。
四、构建Vue前端项目
1、安装node.js,查看是否安装成功:
$node –v
2、使用淘宝NPM 镜像,使用cnpm 命令来安装模块:
$npm install -g cnpm --registry=https://registry.npm.taobao.org
3、先用cnpm安装vue-cli脚手架工具(vue-cli是官方脚手架工具,能迅速帮你搭建起vue项目的框架):
$cnpm install -g vue-cli
4、cd 到 Ats_Web,新建一个前端工程目录template,根据提示按回车,安装中把vue-router选上,我们须要它来做前端路由
$vue-init webpack template
5、进入 template,运行命令来安装vue所须要的node依赖
$cd template
$npm install //安装vue所须要的node依赖
$npm run dev //run起来
打开浏览器http://localhost:8080/ 能打开就配好了
7、我们在src/component文件夹下新建一个名为BookTest.vue的组件,通过调用之前在Django上写好的api,实现添加书籍和展示书籍信息的功能。在样式组件上我们使用了饿了么团队推出的element-ui,这是一套专门匹配Vue.js框架的功能样式组件。
(1). npm 安装element-ui命令:$npm i element-ui –S
(2).在main.js中引入 整个Element,就可以使用了,详细的用法可以去官网查看。
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI)
(3)创建BookTest.vue,下面的是自己随便写的,刚学vue不久,可以参考一下:
添加
8、在src/router目录的index.js中,我们把新建的BookTest组件,配置到vue-router路由中:
import BookTest from '@/components/BookTest'
export default new Router({
routes: [
{
path: '/',
name: 'BookTest',
component: BookTest
}
]
})
9、使用axios来进行http请求。
安装: $cnpm install axios
安装依赖: $cnpm install --save axios vue-axios
配置模板:在main.js中引入axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
10.如果发现列表抓取不到数据,可能是出现了跨域问题,打开浏览器console确认:
11、这时候我们须要在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', #add
'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 #add
12、在前端工程目录下,输入npm run build,如果项目没有错误的话,就能够看到所有的组件、css、图片等都被webpack自动打包到dist目录下了。
目前我们已经分别完成了Django后端和Vue前端工程的创建和编写,但实际上它们是运行在各自的服务器上,和我们的要求是不一致的。因此我们须要把Django的TemplateView指向我们刚才生成的前端dist文件即可.
1、 找到project目录的urls.py,使用通用视图创建最简单的模板控制器,访问 “/” 时直接返回 index.html:
2、 上一步使用了Django的模板系统,所以需要配置一下模板使Django知道从哪里找到index.html。在project目录的settings.py下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [],
'DIRS': ['template/dist'], #update
'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',
],
},
},
]
3、 我们还需要配置一下静态文件的搜索路径。同样是project目录的settings.py下:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "template/dist/static"),
]
4、 配置完成,我们在project目录下输入命令python manage.py runserver,就能够看到我们的前端页面在浏览器上展现:
注意服务的端口已经是Django服务的8000而不是node服务的8080了。
前端部分修改后,Django服务的8000页面不会实时更新,需要重新执行npm run build打包到dist目录下,Django的
端口8000才会有变化。
至此,成功完成了构建。耶!