技术栈node.js, vue.js, axios, python, django, orm, restful api, djangorestframework, mysql, nginx, jenkins. 技术栈环境配置操作系统前端Node.jsVue.js后端PythonDjango数据库MySQL代理Nginx持续集成Jenkins项目搭建创建后端工程创建RESTful API创建前端工程前端调后端接口前后端结合Nginx转发持续集成 环境配置操作系统Windows 7 旗舰版,Service Pack 1。 前端Node.js>node -v v12.18.0 >npm -v 6.14.4 Vue.js>vue -V(大写) @vue/cli 4.4.1 后端Python>python --version Python 3.7.2 Django>python -m django --version 3.0.7 数据库MySQL>mysqladmin --version mysqladmin Ver 8.0.19 for Win64 on x86_64 (MySQL Community Server - GPL) 命令行登录mysql, >mysql -u root -p Enter password: ****** 查询数据库, mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | new_schema | | performance_schema | | sakila | | sys | | world | +--------------------+ 7 rows in set (0.00 sec) 代理Nginx在nginx安装目录执行start nginx ,浏览器访问http://localhost:80,
持续集成Jenkins安装后,会自动打开http://localhost:8080/,
软件安装过程就不赘述了,聪明的你一定知道怎么安。 项目搭建本文的目的是走通整个项目的链路,于是会“弱化”掉系统功能的实现。 创建后端工程执行django-admin startproject djangotest 创建项目。 cd djangotest ,执行python manage.py startapp myapp 创建应用。
python manage.py runserver ,启动服务,访问http://localhost:8000/,
创建RESTful API安装mysqlclient和djangorestframework, pip --default-timeout=6000 install -i https://pypi.tuna./simple mysqlclient pip --default-timeout=6000 install -i https://pypi.tuna./simple djangorestframework
在settings.py中,添加'rest_framework'和'myapp', INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',
'rest_framework',
'myapp', ]
同时修改数据库配置, DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': 3306, 'NAME': 'world', 'USER': 'root', 'PASSWORD': '123456' } }
在myapp\models.py添加model,model叫做HellloDjango,有2个字段id和name, from django.db import models
# Create your models here.
class HelloDjango(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(null=False, max_length=64, unique=True)
执行python manage.py makemigrations ,提交, >python manage.py makemigrations Migrations for 'myapp': myapp\migrations\0001_initial.py - Create model HelloDjango
执行python manage.py migrate ,创建, >python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, myapp, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying myapp.0001_initial... OK Applying sessions.0001_initial... OK
看看数据库,新增了auth_和django_开头的表,以及model映射的表myapp_hellodjango, mysql> show tables; +----------------------------+ | Tables_in_world | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | city | | country | | countrylanguage | | django_admin_log | | django_content_type | | django_migrations | | django_session | | myapp_hellodjango | +----------------------------+ 14 rows in set (0.00 sec)
插入2条测试数据, mysql> insert into myapp_hellodjango(name) values('hello'); Query OK, 1 row affected (0.09 sec)
mysql> insert into myapp_hellodjango(name) values('django'); Query OK, 1 row affected (0.20 sec)
mysql> select * from myapp_hellodjango; +----+--------+ | id | name | +----+--------+ | 2 | django | | 1 | hello | +----+--------+ 2 rows in set (0.00 sec)
照着官网的例子,在myapp目录下新增urls.py,添加rest代码, from django.conf.urls import url, include from rest_framework import routers, serializers, viewsets
from .models import HelloDjango
# Serializers define the API representation. class HelloSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = HelloDjango fields = ['id', 'name']
# ViewSets define the view behavior. class HelloViewSet(viewsets.ModelViewSet): queryset = HelloDjango.objects.all() serializer_class = HelloSerializer
# Routers provide an easy way of automatically determining the URL conf. router = routers.DefaultRouter() router.register(r'hello', HelloViewSet)
urlpatterns = [ url(r'demo/', include(router.urls)), ]
在djangotest下的urls.py中添加路由, from django.contrib import admin from django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('myapp.urls')) ]
通过这2个urls.py文件的指定,api接口的路径为,/api/demo/hello。 执行python manage.py runserver 启动服务,使用postman来调用http://127.0.0.1:8000/api/demo/hello/。先发1个post请求,往数据库新增1条数据,
再发1个get请求,会看到返回了3条数据,2条预先插入的数据,1条post请求新增的数据,
创建前端工程在djangotest根目录下,执行vue create vuetest ,创建vue工程。 默认安装,一路回车,啪啪啪。 开始创建, Vue CLI v4.4.1 a Creating project in D:\cicd\vuetest. a Initializing git repository... aa Installing CLI plugins. This might take a while...
创建成功, a Successfully created project vuetest. a Get started with the following commands:
$ cd vuetest $ npm run serve
执行cd vuetest 和npm run serve ,前端工程就启动起来了,访问http://localhost:8080/,Welcome to Your Vue.js App,
前端调后端接口此时djangotest的目录结构为, ├─djangotest │ ├─djangotest │ ├─myapp # app │ ├─vuetest # 前端 │ ├─manage.py
修改vuetest\src\components\HelloWorld.vue,添加{{info}} ,用来展示后端api返回的数据, <div class="hello"> {{info}} <h1>{{ msg }}</h1>
同时在<script> 中使用axios添加ajax请求,请求http://127.0.0.1:8000/api/demo/hello/,将response.data赋值给info, <script> export default { name: 'HelloWorld', props: { msg: String }, data() { return { info: 123 } }, mounted () { this.$axios .get('http://127.0.0.1:8000/api/demo/hello/') .then(response => (this.info = response.data)) .catch(function (error) { // 请求失败处理 console.log(error); }); } } </script>
为了运行起来,需要安装axios, npm install --save axios
并在vuetest\src\main.js中引入, import Vue from 'vue' import App from './App.vue' import axios from 'axios'
Vue.config.productionTip = false
Vue.prototype.$axios = axios;
new Vue({ render: h => h(App) }).$mount('#app')
分别启动后端和前端服务, python manage.py runserver
cd vuetest npm run serve
嚯!ajax请求失败了,F12可以看到报错信息, localhost/:1 Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/demo/hello/' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. django的端口是8000,vue的端口是8080,vue在请求django的时候,出现了跨域问题。浏览器有个同源策略,域名+端口+协议都相同才认为是同一来源。 通过配置django来解决,先安装django-cors-headers, pip install django-cors-headers
在settings.py中添加中间件和开关, MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', # 添加 '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 # 添加
此时vue就可以请求到django提供的接口了,http://localhost:8080/
前后端结合在vuetest 目录下创建vue.config.js ,这是因为django只能识别static目录下的静态文件,这里指定vue生成静态文件时套一层static目录, module.exports = { assetsDir: 'static' };
在vuetest目录下执行npm run build ,生成静态文件到vuetest/dist文件夹。 修改urls.py,指定django的模板视图, from django.conf.urls import url 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('myapp.urls')), url(r'^$', TemplateView.as_view(template_name="index.html")), ]
在settings.py中配置模板目录为dist文件夹, TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['vuetest/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', ], }, }, ]
指定静态文件目录为vuetest/dist/static, # Add for vuejs STATICFILES_DIRS = [ os.path.join(BASE_DIR, "vuetest/dist/static"), ]
浏览器访问http://localhost:8000/,显示的不再是django的欢迎页面,而是vue的页面。 前后端结合完成。vue的8080可以停了。
Nginx转发nginx常用3个命令,启动,重新加载,停止, nginx start nginx -s reload nginx -s stop
修改\conf\nginx.conf,监听端口改为8090,添加转发proxy_pass http://localhost:8000; server { listen 8090; server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { root html; index index.html index.htm; proxy_pass http://localhost:8000; }
执行nginx start ,浏览器访问http://localhost:8090/,也能正常访问djangotest。 通过nginx将8090转发到了8000。 持续集成本来想弄个pipline的,无奈家里这台破机器安装失败,windows也没有linux对jenkins支持好,只能将就做个鸡肋版本。 New Item,命名为vuetest,添加vue的build脚本,
New Item,命名为djangotest,添加django的build脚本,
直接执行会报错python不是可运行命令。添加python环境变量,在首页左下角,
添加环境变量并保存,
建好的这2个job就可以用来编译vue和启动django了,
|