写在前面
最近两个月,学会了微信小程序,学会了Flask,接着又学会了VUE前端开发,学会了docker,gunicorn,nginx部署,独立Web开发的能力终于GET了。
内心喜悦,写文总结,记录分享。本文主要针对入门学习,希望对大家有所帮助。
作为程序员,Web开发确实很有必要去学习。因为整个互联网的核心技术就是Web开发技术。学会了Web开发,对于整个互联网的认知,对于整个编程世界的认知,都会有非常大的提升。
Flask框架
Python三大主流Web框架:Django,Flask,Tornado。
对于本人,Django入门艰难,Tornado没有接触,Flask一见钟情。
Flask,拉起一个网站,简直太简单了,简单即是美,怎不惹人爱。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Flask,拉起一个API服务后端,亦是如此简单,如此优雅。
from flask import Flask
from flask import jsonify
app = Flask(__name__)
@app.route('/api/user',methods=['GET'])
def get_user():
return jsonify(code=200, msg="用户查询成功!",username = '张三',userphone = '18288889999')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Flask做API服务后端的入门学习
做API服务后端,主要是三块内容:路由,数据库,身份验证。(不需要 渲染 这块东西了)
from flask import Flask
from flask import jsonify
from flask import request
from Tools.dbmanager import DBManager
from Tools.decoratormanager import session_jwt_verification
app = Flask(__name__)
@app.route("/bumen",methods=['GET'])
@session_jwt_verification
def goto_bumen_search():
###############查询部门###############
sqlstring0 = "SELECT id,bumenname,bumentips FROM jr_bumen"
data0 = DBManager().executeQueryall(sqlstring0)
if data0 == False:
return_data = dict()
return_data['code'] = 5000
return_data['msg'] = "数据库连接异常!"
return jsonify(return_data)
if data0 == None:
return_data = dict()
return_data['code'] = 5001
return_data['msg'] = "没有部门数据!"
return jsonify(return_data)
if data0 != None:
return_data = dict()
return_data['code'] = 200
return_data['msg'] = "查询成功!"
return_data['bumendatas'] = data0
return jsonify(return_data)
@app.route("/bumen",methods=['POST'])
@session_jwt_verification
def goto_bumen_add():
data = request.get_json()
bumen_name = data['bumenName']
bumen_tips = data['bumenTips']
###############新增部门###############
sqlstring0 = f"INSERT INTO jr_bumen (bumenname,bumentips) VALUES ('{bumen_name}','{bumen_tips}')"
data0 = DBManager().executeQueryID(sqlstring0)
if data0 == False:
return_data = dict()
return_data['code'] = 5000
return_data['msg'] = "数据库连接异常!"
return jsonify(return_data)
if data0 != None:
return_data = dict()
return_data['code'] = 200
return_data['msg'] = "部门添加成功!"
return_data['bumenid'] = data0
return jsonify(return_data)
@app.route("/bumen",methods=['PUT'])
@session_jwt_verification
def goto_bumen_alter():
data = request.get_json()
bumen_id = data['bumenId']
bumen_name = data['bumenName']
bumen_tips = data['bumenTips']
###############更新部门###############
sqlstring0 = f"UPDATE jr_bumen SET bumenname='{bumen_name}',bumentips='{bumen_tips}' WHERE id= {bumen_id}"
data0 = DBManager().executeQueryNO(sqlstring0)
if data0 == False:
return_data = dict()
return_data['code'] = 5000
return_data['msg'] = "数据库连接异常!"
return jsonify(return_data)
if data0 == True:
return_data = dict()
return_data['code'] = 200
return_data['msg'] = "部门修改成功!"
return jsonify(return_data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
1.关于数据库
上例中的dbmanager 是本人自己写的数据库处理类,之前做过分享。
文章链接:《python操作mysql数据库的精美实用模块》
如果要用ORM,那就上Flask-SQLAlchemy库。
(ORM,相关知识,自行百度)
2.关于身份验证
上例中的dsession_jwt_verification装饰器,是自定义的,用了第三方库:pyjwt。
(JWT,相关知识,自行百度)
from flask import request
from flask import jsonify
from flask import g
from functools import wraps
import jwt
############################################################
# 装饰器管理模块
############################################################
def session_jwt_verification(view_func):
@wraps(view_func) # wraps函数的作用是将wrapper内层函数的属性设置为被装饰函数view_func的属性
def verify_view_func(*args, **kwargs):
try:
session_jwt = request.headers['session-jwt']
payload = jwt.decode(session_jwt, "my_jwt_secret", algorithms=['HS256'])
session_data = payload.get('userid')
g.userid = session_data
except Exception:
return jsonify(code=5901, msg="身份认证失败!")
###################################################################################
return view_func(*args, **kwargs)
###################################################################################
return verify_view_func
3.关于路由
实际项目中,路由这里有个问题,当我们的项目越来越大,API越来越多时,不可能把所有路由都写在一个主文件里面吧,这时就需要想办法拆分路由了。
什么办法呢?就是蓝图BluePrint。对,蓝图的作用就是拆分路由。对于蓝图,有这个理解就够了。
再配合工厂函数(对app进行统一加工处理的函数),最后的主文件变成了这样:
from flask import Flask
from Apis.login import login_api
from Apis.userdata import userdata_api
from Tools.config import config_map
####################################################################################################
# 工厂函数,对app进行加工处理
def create_app(config_name):
app =Flask(__name__)
app.config.from_object(config_map[config_name])
###注册API蓝图,并指定其对应的前缀(url_prefix)#######################
app.register_blueprint(login_api, url_prefix="/api/login")
app.register_blueprint(userdata_api, url_prefix="/api/userdata")
###初始化app的ORM,根据实际需要开启###################################
# from app.models import db
# db.init_app(app)
###初始化app的跨域,根据实际需要开启###################################
# from flask_cors import CORS
# cors = CORS()
# cors.init_app(app)
###初始化app的邮件,根据实际需要开启###################################
# from flask_mail import Mail
# mail = Mail()
# mail.init_app(app)
return app
app = create_app(config_name='development')
#####首页视图函数,留着方便测试#############################################################
@app.route('/')
def index():
return "Jrsoft Api Server"
##################################################################################
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
整个项目的文件目录是这样:
flask-example/
├── Apis
│ ├── login.py
│ └── userdata.py
├── Tools
│ ├── config.py
│ ├── dbmanager.py
│ └── decoratormanager.py
└── main.py
4.其他一些说明
Flask做API服务后端,相关的知识点还是蛮多的,需要自己找资料,逐一消化理解。核心内容就是上述三块:路由,数据库,身份验证。
当然,做API服务后端,还有一些其他框架,比较火爆强劲的就有FastAPI,大家可以了解一下,长得跟Flask有点像,但底层跟Flask不一样。(反正我没用,还是用的Flask)
还有Flask项目本身的开发大神 李辉 做的API框架:APIFlask,可以关注一下,是基于Flask开发的。(这个框架成熟后,我会用起来)
微信小程序的入门学习
好了,后端Flask搞定,咱接着说前端,先说微信小程序吧,然后再说Vue。
微信小程序,其官方文档就很详尽了,基本上看官方文档就足够了,当然根据自身情况,再去B站找些视频看看,辅助学习就可以了,没必要买书了。
链接在此:微信小程序官方文档
官方文档之中,有一份《小程序开发指南》,其实就是新手入门指南。入门必看!多看几遍!随着自身项目,边看边做边学,基本就会了。
而开发指南之中,又有一小节,文档之中一笔带过,但是你绝不可错过,叫【2.3.6 官方样式库】。
为了减轻开发者样式开发的工作量,我们提供了WeUI.wxss基础样式库。
WeUI是一套与微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。包含button、cell、dialog、progress、toast、article、actionsheet、icon等各式原生。
具体使用文档可参考:https://github.com/Tencent/weui-wxss
作为独立开发者,假如没有这种东西,难道让我们自己去写样式去搞UI设计吗?这要开发到何年马月!
类似WeUI,还有一个有赞出品的UI 组件库,也非常有名,美观而好用,叫:Vant
Vant的官网:https://vant-contrib.gitee.io/vant-weapp
文档很详尽,入手很简单,自己去看吧。
Vue的入门学习
Flask做API服务后端搞定了,微信小程序也学会搞定了,想着是时候回头搞网站了吧。
Flask是web框架,本就是搞网站用的,搞网站就要用到Flask的网页渲染功能。
Flask的网页渲染功能,主要靠的就是:Jinja2模板引擎和render_template渲染函数。
学这块内容时,我是比较烦的,可能习惯了以前从事游戏开发时前后端分离的开发思维,这种前端夹着后端,傻傻分不清了,学着就有点难受,也不好学进去。
想想我都用Flask做API服务后端,WEB开发前后端分离又是大势所趋,索性Flask的渲染不学了,火热的前端框架Vue搞起了!
要学Vue,当然先要学Node.js,要会NPM。这Node.js的NPM就如同Python的pip,都是包管理工具。
Vue之下,类似微信小程序的WeUI和Vant,有一个饿了么出品的UI组件库,也非常有名,叫:ElementUI。
Vue有Vue2和Vue3两个版本,我直接用的Vue3,对应的ElementUI版本叫:ElementUI-plus。
ElementUI-plus的官网:https://element-plus.gitee.io/zh-CN/
另外,其实类似WeUI,Vant,ElementUI这样的UI样式库和组件库,还有不少,如:贤心的LayUI,阿里的 Ant Design......
在这里,真的要感谢这些UI样式库和组件库的分享公司,团队或大神,没有这些样式库和组件库,像我这样的个体开发者真的都不知道怎么在web开发上继续下去。
之前,我在web开发上的学习,就是卡在了前端页面的构建上,内心形成了一种恐惧。而自从了解到有这些样式库和组件库的存在,前端瞬间变得轻松简单了,开发瞬间变得美好起来。
Docker的入门学习
前后端搞定,代码开发完成,最后当然要放到真正运行的服务器上,这就是部署了。
高级的部署方法是基于容器进行部署。Docker 就是目前最流行的容器平台。
(Docker ,相关知识,自行百度)
微信小程序的部署,直接上传代码即可,下面主要分享Flask+Vue的网站部署
1.项目目录结构
myweb_project/
│
├── flask
│ ├── Dockerfile
│ ├── gunicorn.config.py
│ └── flask_app # flask项目的代码
│
├── mysql
│ ├── Dockerfile
│ └── myweb.sql
│
├── nginxvue
│ ├── dist # 打包的vue项目
│ ├── Dockerfile
│ └── nginx.conf
│
└──docker-compose.yml
2.Docker+Gunicorn 部署 flask后端
gunicorn.config.py文件如下:
import multiprocessing
bind = '0.0.0.0:9191' # 监听内网端口80
backlog = 512
timeout = 30
worker_class = 'gevent' # 工作模式协程
workers = multiprocessing.cpu_count() * 2 + 1 # 并行工作进程数
threads = 2 # 指定每个工作者的线程数
pidfile = 'gunicorn.pid' # 设置进程文件目录
loglevel = 'info' # 设置日志记录水平
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
accesslog = "gunicorn_access.log" # 访问信息日志文件
errorlog = "gunicorn_error.log" # 错误信息日志文件
reload=True # 代码发生变化是否自动重启
Dockerfile文件如下:
FROM python:3.8
WORKDIR /Project/jrsoftdemo
COPY . .
RUN pip install -r Tools/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD gunicorn -k gevent -w 5 -b 0.0.0.0:8080 backend:app
3.Docker+Nginx 部署 Vue前端
nginx.conf文件如下:
server {
listen 8080;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log error;
location / { # 直接匹配端口返回前端
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /api/ { # 匹配api的,转发给后端,
rewrite /api/(.*) /$1 break;
proxy_pass http://192.168.99.100:9999; # 这里是宿主机的ip
}
}
Dockerfile文件如下:
# 设置基础镜像
FROM nginx
# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
COPY dist/ /usr/share/nginx/html/
#用本地的 nginx.conf 配置来替换nginx镜像里的默认配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
4.Docker部署 mysql数据库
如果你的项目,数据库也需要Docker部署,当然也是可以的。
Dockerfile文件如下:
FROM mysql:5.7.20
部署成功之后,数据库软件通过IP连入,便可查看管理。
5.Docker的相关命令
# 创建镜像
docker build -t jrsoftflask .
# 启动生产环境
docker run -p 9999:9191 --name jrsoft_demo -d jrsoftflask
# 查看镜像
docker images
# 删除镜像
docker rmi -f e7cd0fde3f42
# 进入docker镜像环境
docker run -it jrsoftflask /bin/bash
# 列出运行容器
docker ps
# 列出全部容器
docker ps -a
# docker远程服务器部署——方案一:tar打包法
# 生成tar
docker save jrsoftflask>images.tar
# 加载tar
docker load < images.tar
# docker远程服务器部署——方案二:镜像云仓库法
# 将本地镜像推到[远程仓库]--DockerHub/阿里云Docker仓库/腾讯云Docker仓库
docker push 178.104.162.39/dev/vdi-controller:arm0324
# 从[远程仓库]拉取镜像--DockerHub/阿里云Docker仓库/腾讯云Docker仓库
docker pull 178.104.162.39/dev/vdi-controller:arm0324
6.docker-compose编排
像Flask+微信小程序,只需要用一个docker容器部署Flask就可以了,自然不需要docker-compose编排。
而像Flask+Vue项目,用到多个docker容器,那用docker-compose编排,一键拉起,自然更加方便。
docker-compose.yml文件如下:
version: '3'
services:
mysql:
build: ./mysql
ports:
- "3306:3306"
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=mypws123456789
restart: always
flask:
build: ./flask
ports:
- "9999:9191"
container_name: flask
restart: always
volumes:
- "./flask/lab_app:/root/lab_app"
nginx:
build: ./nginxvue
ports:
- "8080:8080"
container_name: nginxvue
# 启动命令
docker-compose up -d
7.注意事项
Docker部署,需要注意每个容器的IP和端口,假若设置不对就连不上了。
在docker-compose编排的时候,可进行相应的网络设置,上面文件并未涉及,大家可自行研究。
自学方法
1.git和github
现在的程序员,git基本必学了,没什么好说的。一般用用的话,掌握几条命令就可以了
# 创建仓库
git init
# 添加到暂存区
git add .
# 提交到仓库
git commit -m '提交注释'
# 关联远程仓库
git remote add origin git@github.com:......
# 推送到远程仓库
git push -u origin master
# 克隆远程仓库
git clone git@github.com:......
学习git,自然会用上github。github上好东西太多了,想找什么源码,尽管去上面搜索好了。
所以,这里有个入门捷径:先去github,搜几个简单的项目源码,下载下来进行学习,看看别人都是怎么做的,最简单的项目是怎么搭建的,如此入门再好不过了!
后面有时间有机会,我也会写几个入门项目源码,上传到github,届时分享给大家。
2.自己的项目
看别人的文章,看别人的视频,看别人的源码,终究是顺着别人的思维,看的时候貌似都会了,其实往往离真正会做还有一段距离。
所以,这里有个入门捷径:学东西前,先有一个自己的项目,越现实越具体越好。
不管是自己主动构想的项目,还是他人被动赋予的项目,都很好,只要有了项目,便有了明确的目标。
然后边做边学,边学边做,学以致用,知行合一,如此最快,做才是真正的得到!
3.目标拆分法
目标往往很大,任务往往艰巨。不要怕,拆分他!
目标拆分法是做事万能法,不管是做项目,还是学习,不管是写程序,还是写小说......
目标越大,越需要拆分,拆分成一个个小目标,一个个可执行的不让人恐惧的小目标。
然后一个小目标一个小目标的去完成,像做游戏任务一样,像玩游戏闯关一样,按部就班,逐个击破即可。
这目标拆分法,也是管理学中的方法,也是游戏设计中的一大核心要义。
游戏有四要素:目标,规则,反馈,自愿参与。
你看,你将学习目标拆分成多个可执行的小目标后,还可以给每个小目标设定完成奖励,如此一来,你可以将学习转化为游戏一般好玩,这叫学习游戏化。
写在最后,网站开发,我的心愿
大约10年以前,不做游戏策划之后,便萌生了一个想法:要学会网站开发,做自己想做的网站。
而在正式转做程序员之后,这个想法也便随之变得愈加强烈和执着,已然成为了人生的必达目标,人生的一个心愿。
而且,时常心想:一个程序员,如果连网站开发都不会,当别人问你什么工作时,好意思跟别人说自己是程序员,是软件开发工程师吗?
所以,很早以前,便看了html,css,javascript,但是看懂了又如何?真正搞起网站来,依然一脸懵逼。
后来,为了搭建网站,也接触了wordpress等等各种搭建网站的工具,但这些毕竟都只是工具,并不是自己想要的能力——真正网站开发的能力。
后来会了python,便开始学python的web框架django,可是对我来说django似乎太复杂了,起手学了两次,每次花了两三天还感觉门都没摸着,也便兴味索然,算了算了。
后来工作之中,同事请我帮忙搭建一个API服务,那时我也不真正清楚什么是API服务,但我自信我大python啥不能干,网上一搜,短短几行代码便能搭建,so easy,便应下了同事的任务,帮忙完成了这个API服务。而这一次任务中,用的正是python的另一个web框架——flask。
flask,短短几行代码,简单明了,便能搭建api服务,便能搭建网站,简直太棒了,一见钟情。
于是,正式开始学习flask,以书本《Flask Web开发》(米格尔格林贝格 著)为主要教材,以B站大神们分享的flask视频为辅助学习。
《Flask Web开发》,逐字逐句阅读,逐行代码敲下,学了大半个月,仿佛都学下来了,其实很多概念并不清晰,很多东西把握不住。自己很清楚,真正动手去做,根本没把握独自开发一个网站,所以说到底,知识还是没有内化,功夫还是没有学到。于是,停了停,又放了一段时间。
后来,那个同事又找我帮忙做微信小程序。微信小程序开发,我也是摸了好几次,也想学也是一直学不会,但现在有了flask的半吊子功夫,心里是有点底的,知道整体是怎么搭建的,都需要哪些知识技能,而且我内心太喜欢这种全新的实际项目了,因为我知道,在这种实际项目上,边做边学,又有项目的现实约束,学东西才是最快的。
于是,接下来,大概一个月,我真正学会了微信小程序,学会了Flask,接着一个月,又学会了VUE前端开发,学会了docker,gunicorn,nginx部署,当然称不上完全了解和精通,但独立搭建网站已经没有问题了,更深入的原理知识根据实际需求再去了解即可。总之,当前的程度对我来说基本足够了,此生一个心愿也算了了。
心愿已了,技能获得,内心欢喜,写下此文,以作总结,留做记录,分享于此。