技术栈
node.js, vue.js, axios, python, django, orm, restful api, djangorestframework, mysql, nginx, jenkins.
环境配置
操作系统
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.tsinghua.edu.cn/simple mysqlclient
pip --default-timeout=6000 install -i https://pypi.tuna.tsinghua.edu.cn/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脚本,
d:
cd D:\\cicd\\djangotest\\vuetest
npm run build
New Item,命名为djangotest,添加django的build脚本,
d:
cd D:\\cicd\\djangotest
python manage.py runserver
直接执行会报错python不是可运行命令。添加python环境变量,在首页左下角,
把路径D:\\Python37添加为环境变量path并保存,
建好的这2个job就可以用来编译vue和启动django了,
版权申明:本文为博主原创文章,转载请保留原文链接及作者。