侃侃
最近挺长时间没码代码了,觉得是时候该来写篇总结性文章了,但是想了好久都没找到有啥可写的。后面翻了一下以前写的博客,好像有关于python-web的博文一篇都没有,那么就从这篇开始吧。
我接触python-web是从建立自己博客的念头开始的,那时候总想有个自己狂拽酷炫吊炸天的网站,但是怎么建立用什么做一头雾水,磕磕绊绊的搞了半个多月算是懵懵懂懂的入门了。
据我了解的python-web框架有flask和django,而这两者的区别呢,我也不是很懂,我没用过django,只是大慨知道flask跟django呢,在我个人看来一个就像是毛坯房,一个是精装房,看个人喜好吧。
首先我比较喜欢折腾,所以肯定首选是flask,可塑性高,方便简单。再者呢,还不是因为穷!你看这精装房,你看这配饰,多高级!
哈哈哈,说些玩笑话,其实还是因为看了下两者源码的对比,发现flask好像比较简洁明了,头不会那么快秃。
好了,步入正题,该文我将会简单的使用flask来进行一些总结,最后再大概说一下怎么在云服务器上运行flask并布置网站。
简单尝试
第一步不用说肯定是pip install flask,使用国内源比较快。
pip install -i https://pypi.doubanio.com/simple
接着看图示。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/5/6 19:55
# @Author : Cxk
# @File : run.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello Cxk!
if __name__ == '__main__':
app.run(debug=True)
可以看到只要几步就可以在一个网页显示字符,大概分为四个步骤,导入包,创建实例,创建路由函数,调用实例。
在这里我就只跟大家讲讲什么叫路由,实际上它就是一个装饰器,@app.route(’/’),把函数绑定到固定的url上面,例如现在是(’/’),默认是http://127.0.0.1:5000/主页面,当我们在上面加个名字,那么当你打开http://127.0.0.1:5000/时它是不会显示的。例如我们创建@app.route(’/cxk’),我们再试一试。
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
不出意外,我们把默认路由去了改为(’/cxk’)打开页面显示没找到。而我们手动给它加上/cxk后可以看到又回到了刚才的主页面,其实路由就是用来区分不同网页,下面我们再来试试返回一个网页,刚刚我们只是返回一个字符串。
首先现在项目文件下建立,两个文件夹,一个static,一个templates。 static是存放静态文件的文件夹,templates是用来存放网页源代码的文件夹,static我们暂时用不到,先在templates下创建一个网页文件index.html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello,CXk!
</body>
</html>
然后我们将源码改一下,加一个 render_template模板。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/5/6 19:55
# @Author : Cxk
# @File : run.py
from flask import Flask, render_template
app = Flask(__name__
@app.route('/')
def index():
return render_template('index.html')
@app.route('/cxk')
def cxk():
return 'Hello,CXk!'
if __name__ == '__main__':
app.run(debug=True)
有没发现,两个文字虽然一样,但是网页中的字体比较好看,还有网页顶端的title,直接返回字符串title它是直接给你一个url名,而网页是自己设置的
进阶使用
有了以上基础,我们就可以来做比较有意义的东西了,接口。这里呢,我拿三端登录作为例子,所谓三端呢,就是网页端,pc端,微信小程序端,对应–网页,电脑,手机。
设置接口
上面忘讲了前后端数据传递,这里传递页面时我加上两个参数,在前端页面上显示账号:,密码:,分别对应到页面上的
{{name}},{{password}},事实就是这么简单,{{}},两个大括号的事,想了解更多自己百度下。
我直接判断如果帐号密码是123456那么就登录成功,反之则失败。返回则是json格式数据,在网页端其实我们可以直接返回其他页面,但是为了在pc端跟小程序好处理,这里我们返回json格式比较好。
<input id="username" type="text" name='username' autocomplete="off" placeholder={{name}}>
<input id="password" type="password" name='password' autocomplete="off" placeholder={{password}}>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/5/6 19:55
# @Author : Cxk
# @File : run.py
from flask import Flask, render_template,request
import json
app = Flask(__name__)
@app.route('/')
def index():
name='帐号:'
password='密码:'
return render_template('index.html',name=name,password=password)
@app.route('/login', methods=['POST'])
def login():
try:
# 小程序获取post数据
if request.data:
data = request.data.decode('utf-8')
data_json = json.loads(data)
username = data_json['username']
password = data_json['password']
#网页以及PC端
else:
username = request.form.get('username')
password = request.form.get('password')
if username == '123456' and password == '123456':
return json.dumps({"code":200,"msg": "登录成功"},ensure_ascii=False)
else:
return json.dumps({"code": 404, "msg": "登录失败"}, ensure_ascii=False)
except:
return json.dumps({"code": 500, "msg": "后台错误"}, ensure_ascii=False)
if __name__ == '__main__':
app.run(debug=True)
网页端
这里是我网上随便找的一个登录界面,挺好看的,我自己改版了下,图片资源放在static下images文件夹下,下面是三个资源文件,分别是backgroud.png,password.png,login.png,emil.png
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>登录</title>
<style>
* { margin: 0; padding: 0; }
html { height: 100%; }
body { height: 100%; background: #fff url(static/images/backgroud.png) 50% 50% no-repeat; background-size: cover;}
.dowebok { position: absolute; left: 50%; top: 50%; width: 430px; height: 550px; margin: -300px 0 0 -215px; border: 1px solid #fff; border-radius: 20px; overflow: hidden;}
.logo { width: 75px; height: 75px; margin: 50px auto 50px; background: url(static/images/login.png) 0 0 no-repeat; }
.form-item { position: relative; width: 360px; margin: 0 auto; padding-bottom: 30px;}
.form-item input { width: 288px; height: 48px; padding-left: 70px; border: 1px solid #fff; border-radius: 25px; font-size: 18px; color: #fff; background-color: transparent; outline: none;}
.form-item button { width: 360px; height: 50px; border: 0; border-radius: 25px; font-size: 18px; color: #1f6f4a; outline: none; cursor: pointer; background-color: #fff; }
#username { background: url(static/images/emil.png) 11px 3px no-repeat; }
#password { background: url(static/images/password.png) 11px 3px no-repeat; }
.reg-bar { width: 360px; margin: 20px auto 0; font-size: 14px; overflow: hidden;}
.reg-bar a { color: #fff; text-decoration: none; }
.reg-bar a:hover { text-decoration: underline; }
.reg-bar .reg { float: left; }
.reg-bar .forget { float: right; }
.dowebok ::-webkit-input-placeholder { font-size: 18px; line-height: 1.4; color: #fff;}
.dowebok :-moz-placeholder { font-size: 18px; line-height: 1.4; color: #fff;}
.dowebok ::-moz-placeholder { font-size: 18px; line-height: 1.4; color: #fff;}
.dowebok :-ms-input-placeholder { font-size: 18px; line-height: 1.4; color: #fff;}
@media screen and (max-width: 500px) {
* { box-sizing: border-box; }
.dowebok { position: static; width: auto; height: auto; margin: 0 30px; border: 0; border-radius: 0; }
.logo { margin: 50px auto; }
.form-item { width: auto; }
.form-item input, .form-item button, .reg-bar { width: 100%; }
}
</style>
</head>
<body>
<div class="dowebok">
<div class="logo"></div>
<form action="login" method="post">
<div class="form-item">
<input id="username" type="text" name='username' autocomplete="off" placeholder={{name}}>
</div>
<div class="form-item">
<input id="password" type="password" name='password' autocomplete="off" placeholder={{password}}>
</div>
<div class="form-item"><button id="submit">登录</button></div>
</form>
</div>
<script src="static/js/jquery.min.js"></script>
</body>
</html>
效果展示
pc端
这里我拿了以前写的人脸识别登录的界面来用,有兴趣的点击传送门。
# -*- coding:utf-8 -*-
#!/usr/bin/env python
# @Time : 2020/5/6 19:55
# @Author : Cxk
# @File : login.py
from tkinter.messagebox import *
from tkinter import *
import requests
class LoginPage(object):
def __init__(self, master=None):
self.root = master
winWidth = 650
winHeight = 400
screenWidth = self.root.winfo_screenwidth()
screenHeight = self.root.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.root.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.root.resizable(0, 0)
self.student_number = StringVar()
self.student_pw = StringVar()
self.createPage()
def createPage(self):
'''
登录页面
1:创建图片组件
2:根目录基础上添加Frame容器
3:Frame容器上添加注册控件
'''
bm=PhotoImage(file=r'cxk.gif')
self.lab3=Label(self.root,image=bm)
self.lab3.bm=bm
self.lab3.pack()
self.page = Frame(self.root)
self.page.pack()
Label(self.page).grid(row=0, stick=W)
Label(self.page, text = ' 学号:').grid(row=1, column=0,stick=W, pady=10)
Entry(self.page, textvariable=self.student_number).grid(row=1, column=1, stick=E)
Label(self.page, text = ' 密码:').grid(row=2, column=0,stick=W, pady=10)
Entry(self.page, textvariable=self.student_pw, show='*').grid(row=2, column=1, stick=E)
Button(self.page, text='学生登录', command=self.student_loginCheck).grid(row=3,column=1)
def student_loginCheck(self):
try:
Student_number=self.student_number.get()
Student_pw=self.student_pw.get()
if Student_number=="" or Student_pw=="":
showinfo(title="错误",message='帐号和密码不能为空!')
else:
data={
'username':Student_number,
'password':Student_pw
}
res=requests.post('http://127.0.0.1:5000/login',data)
if (res.json()['code']==200):
self.page.destroy()
self.lab3.pack_forget()
StudentPage(self.root)
else:
showinfo(title='错误',message='%s'%res.json()['msg'])
except:
showinfo(title='错误',message='未知错误!')
class StudentPage(object):
def __init__(self, master=None):
self.root = master #定义内部变量root
self.root.geometry('%dx%d' % (650, 400)) #设置窗口大小
self.root.resizable(0,0) #防止用户调整尺寸
self.createPage()
def createPage(self):
self.menuPage = MenuFrame(self.root) # 创建不同Frame
class MenuFrame(Frame): # 继承Frame类
def __init__(self, master=None):
Frame.__init__(self, master)
self.root = master #定义内部变量root
self.createPage()
def createPage(self):
strs="登录成功!"
Label(self.root,text=strs,font=("Arial", 30)).pack()
root = Tk() #建立一个根窗口,所有窗口的基础
root.title('学生管理系统')
LoginPage(root)#进入调用登录
root.mainloop()
效果展示
重点代码讲解
我们先获取到前端输入框的字符,然后将该字符进行requests.post带上去提交请求,为啥是post而不是get呢,看前面的代码,我在接口处设置了methods=[‘POST’],表示该处只接受post请求,而一般帐号密码都是post请求的,因为post请求不会在url显示,想了解更多自行百度post与get分别。然后我们根据服务器接口返回的json数据中的“code”进行判定,200表示请求登录成功,看你接口怎么设置。
注意,我们要先将网页源码运行,不然找不到请求的。
Student_number=self.student_number.get()
Student_pw=self.student_pw.get()
if Student_number=="" or Student_pw=="":
showinfo(title="错误",message='帐号和密码不能为空!')
else:
data={
'username':Student_number,
'password':Student_pw
}
res=requests.post('http://127.0.0.1:5000/login',data)
if (res.json()['code']==200):
self.page.destroy()
self.lab3.pack_forget()
StudentPage(self.root)
else:
showinfo(title='错误',message='%s'%res.json()['msg'])
微信小程序
js
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
name:'',
password:''
},
name(e){
this.setData({
name: e.detail.value
})
},
password(e){
this.setData({
password: e.detail.value
})
},
formSubmit: function () {
wx.request({
url: 'http://127.0.0.1:5000/login',
data: {
username: this.data.name,
password: this.data.password
},
method: 'post',
header: {
'content-type': 'application/json'
},
success: function (res) {
var msg=JSON.parse(res.data)
wx.showModal({
title: '提示',
content: msg['msg'],
})
}
})
}
,
onLoad: function () {
},
}
wxml
<view class='container'>
<view class='header'>
<text>登录尝试</text>
</view>
<view class='section'>
<text>帐号:</text>
<input type='number' placeholder='请输入学号' bindinput ="name"/>
</view>
<view class='section'>
<text>密码:</text>
<input password='true' placeholder='请输入密码' bindinput ="password"/>
</view>
<view class='button'>
<button type='primary' form-type='submit' bindtap="formSubmit" >登录</button>
</view>
</view>
wxss
/**index.wxss**/
input{
border: 1px solid #ccc;
width: 310px;
height: 40px;
}
.button{
margin-top: 20px;
}
.header text{
font-size: 25px;
color: #666;
}
效果展示
后记
至此,我们基本了解了flask的七七八八,剩下的就是一堆细节操作以及高端使用,一点一点学,慢慢的我们就会举一反三,其实很多时候敲着敲着就开窍了,比如说这篇文章,其实我也是边敲边理解,以前没尝试过三端合一接口,就脑子想应该可以,然后就动手试了下,不过数据格式是个问题,小程序提交的数据跟网页pc提交的数据不一致,这里弄了好久。。实属坑,最后没办法,用if来判断了,有大佬知道咋回事的留言,不胜感激。
转载:https://blog.csdn.net/Cxk___/article/details/105957225